{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "44a425d0",
   "metadata": {},
   "source": [
    "# Training an Exchange Correlation Functional using Deepchem\n",
    "\n",
    "Author : Advika Vidhyadhiraja : [Linkedin](www.linkedin.com/in/advikavidhyadhiraja) \n",
    "\n",
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1MDEvTitrBreK-Pf0a_F7rNzt-8X7j97g?usp=sharing) "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec83af94",
   "metadata": {},
   "source": [
    "### Brief introduction to Density Functional Theory and Exchange Correlation Functionals"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40a5d2de",
   "metadata": {},
   "source": [
    "   Density-functional theory (DFT) is a theory used to calculate the electronic structure of atoms, molecules, and solids. Its objective is\n",
    "to use the fundamental laws of quantum mechanics to quantitatively\n",
    "comprehend the properties of materials.\n",
    "    \n",
    "   There are serious limitations to the tradional methods used to approximate solutions to the Schrödinger equation of N interacting electrons moving in an external potential. Whereas in DFT, instead of the many-body wave function, the density (n(r)) is a function of three spatial coordinates.\n",
    "    \n",
    "   The many-body electronic ground state can be described using single-particle    equations and an effective potential thanks to the Kohn-Sham theory. The exchange-correlation potential, which accounts for many-body effects, the Hartree potential, which describes the electrostatic electron-electron interaction, and the ionic potential resulting from the atomic cores make up the effective potential.\n",
    "    \n",
    "   The difference between the total exact energy and the total of the rest of the energy terms (such as kinetic energy), is known as the exchange-correlation energy. The exchange-correlation functional is obtained by calculating the functional derivate of the XC energy w.r.t the\n",
    "electron density function. \n",
    "\n",
    "##### References\n",
    "\n",
    "- Encyclopedia of Condensed Matter Physics, 2005. \n",
    "\n",
    "- Mark R. Pederson, Tunna Baruah, in Advances In Atomic, Molecular, and Optical Physics, 2015\n",
    "\n",
    "- Kasim, Muhammad F., and Sam M. Vinko. \"Learning the exchange-correlation functional from nature with fully differentiable density functional theory.\" Physical Review Letters 127.12 (2021): 126403.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61c387b3",
   "metadata": {},
   "source": [
    "### Basic Exchange Correlation Functionals \n",
    "\n",
    "The energy contributors in DFT can be representated as :\n",
    "\n",
    "   $ E_{total} = E_{Kinetic} + E_{electrostatic interactions} + E_{xc}$\n",
    "\n",
    "The first term (Kinetic energy) is calculated using a fictitious non-interacting system. The second term is the electrostatic interactions between electrons and nuclear cores. A potential energy surface is derived using the Born-Oppenheimer approximation to account for the electrostatic repulsion between the nuclear cores.\n",
    "\n",
    "The most commonly used and simplest class of XC functionals are the Local-density approximations (LDA). The LDA assumes variations of the density to be gradual, i.e, it is  based on the homogeneous electron gas model. Which is why it is regarded as the simplest approach to the exchange correlation functional. This class of functionals depend only upon the value of the electronic density at each point in space.\n",
    "\n",
    "The next point in the Jacob's ladder of XC functionals is the Generalized Gradient Approximation (GGA) class, which includes both the\n",
    "density and its gradient.\n",
    "\n",
    "##### References\n",
    "\n",
    "- Voss, J. (2022) Exchange-correlation functionals, Johannes Voss. Available at: https://stanford.edu/~vossj/project/xc-functionals/ (Accessed: April 28, 2023).  \n",
    "\n",
    "- Density-Functional Theory of the Electronic Structure of Molecules,Robert G. Parr and Weitao Yang, Annual Review of Physical Chemistry 1995 46:1,\n",
    "\n",
    "- 701-728\n",
    "R. O. Jones and O. Gunnarsson, Rev. Mod. Phys. 61, 689 (1989)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be6ccda6",
   "metadata": {},
   "source": [
    "### Setup "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9f2cbc0",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install --pre deepchem\n",
    "!pip install git+https://github.com/diffqc/dqc.git\n",
    "!pip install pylibxc2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bac191b3",
   "metadata": {},
   "source": [
    "### Datasets"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51c5497f",
   "metadata": {},
   "source": [
    "There are four types of data points used to train XCModel: atomization energy (AE) calculations, ionization poten- tial (IP) calculations, density profile regulations and den- sity matrix calculations. The ground truth values for the first two types are obtained from NIST databases (Kasim & Vinko, 2021), and the rest are calculated by perform- ing CCSD calculations (using PYSCF). Users do not need to enter the equations used to calculate the total energy for AE and IP data points. We have implemented a DFTYamlLoader class in DeepChem that loads and prepares data, and featurizes the data into standard molecular"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8c9b355",
   "metadata": {},
   "source": [
    "#### DFTYamlLoader and DFT data classes \n",
    "\n",
    "The DFTEntry data class creates and initialises DFTEntry objects from the dataset. This object contains information about the various systems in the datapoint (atoms, molecules and ions) along with the ground truth\n",
    "values. A system in an entry object contains \"moldesc\", \"basis\" and \"spin\"\n",
    "of all the atoms/molecules. These values are to be entered in the DQC or PYSCF format. The systems needs to be entered in a specific order, i.e ; the main atom/molecule needs to be the first element. (This is for objects containing equations, such as ae and ie entry objects). Spin and charge of the system are optional parameters and are considered '0' if not specified. The system number refers to the number of times the systems is present in the molecule - this is for polyatomic molecules and the\n",
    "default value is 1. For example ; system number of Hydrogen in water\n",
    "is 2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "573309a6",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Skipped loading some Tensorflow models, missing a dependency. No module named 'tensorflow'\n",
      "Skipped loading modules with pytorch-geometric dependency, missing a dependency. No module named 'torch_geometric'\n",
      "Skipped loading modules with transformers dependency. No module named 'transformers'\n",
      "cannot import name 'HuggingFaceModel' from 'deepchem.models.torch_models' (/Users/advika_v/Desktop/deepforest/deepchem/deepchem/models/torch_models/__init__.py)\n",
      "Skipped loading modules with pytorch-geometric dependency, missing a dependency. cannot import name 'DMPNN' from 'deepchem.models.torch_models' (/Users/advika_v/Desktop/deepforest/deepchem/deepchem/models/torch_models/__init__.py)\n",
      "Skipped loading some Jax models, missing a dependency. No module named 'jax'\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[<deepchem.feat.dft_data.DFTSystem at 0x1059c3fd0>]"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Example: creating a DFTEntry object \n",
    "from deepchem.feat.dft_data import DFTEntry\n",
    "e_type= 'dm'\n",
    "true_val= 'deepchem/data/tests/dftHF_output.npy'\n",
    "systems = [{'moldesc': 'H 0.86625 0 0; F -0.86625 0 0','basis': '6-311++G(3df,3pd)'}]\n",
    "dm_entry_for_HF = DFTEntry.create(e_type, true_val, systems)\n",
    "\n",
    "#list of systems in an entry object\n",
    "dm_entry_for_HF.get_systems()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f374c95f",
   "metadata": {},
   "source": [
    "#### Calculating ground truth values \n",
    "\n",
    "   For the AE and IE entry types, we use pre- calculated values from the NIST databases. For the DM and Dens datatypes, we calcute the true values using a non-DFT method called CCSD. (we use the PYSCF library to do so) \n",
    "   In this example, we will calculate the initial density matrix for Hydrogen Fluoride. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4d0b3764",
   "metadata": {},
   "outputs": [],
   "source": [
    "# INSTALL PYSCF \n",
    "!pip install pyscf\n",
    "import pyscf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6991ba4a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create a pyscf mol \n",
    "mol = gto.M(atom= 'H 0.86625 0 0; F -0.86625 0 0', basis='6-311++G(3df,3pd)' ,unit=\"Bohr\")\n",
    "mf  = scf.UHF(mol).run()\n",
    "mcc = cc.UCCSD(mf)\n",
    "mcc.kernel()\n",
    "\n",
    "# obtain the total density matrix\n",
    "modm = mcc.make_rdm1()\n",
    "aodm0 = np.dot(mf.mo_coeff[0], np.dot(modm[0], mf.mo_coeff[0].T))\n",
    "aodm1 = np.dot(mf.mo_coeff[1], np.dot(modm[1], mf.mo_coeff[1].T))\n",
    "aodm = aodm0 + aodm1\n",
    "\n",
    "# save the value in a .npy file\n",
    "dm = torch.as_tensor(aodm, dtype=torch.double)\n",
    "outfile = \"output.npy\"\n",
    "np.save(outfile, dm)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eedfaa25",
   "metadata": {},
   "source": [
    "#### An example of the data type format: \n",
    "\n",
    "![](assets/yamldft.png) \n",
    "\n",
    "These values are stored in .yaml files. In case of 'dens' and 'dm', the true value will be replaced by the .npy file name containing the ccsd values."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a74b7d2",
   "metadata": {},
   "source": [
    "### Featurizing and loading the dataset \n",
    "\n",
    "After we have built the data file, we will load it and featurize using the DFTYamlLoader class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "39a7edd2",
   "metadata": {},
   "outputs": [],
   "source": [
    "from deepchem.data.data_loader import DFTYamlLoader\n",
    "#name of the yaml file\n",
    "inputs = 'assets/dft_tutorial.yaml'\n",
    "data = DFTYamlLoader()\n",
    "dataset = data.create_dataset(inputs)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dfd6f0c5",
   "metadata": {},
   "source": [
    "### Layers\n",
    "\n",
    "#### NNXC layers \n",
    "\n",
    "The baseNNXC class can be used to build layers such as the NNLDA layer, where the exchange correlation functional is trained based on the pre-defined LDA  class of functionals. The methods in this class take the electron density as the input and transform it accordingly. For example; The NNLDA layer requires only the density to build an NNXC whereas a GGA based model would require the density gradient as well. This method also takes polarization into account."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ae2915a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Example; using NNLDA layer \n",
    "from deepchem.models.dft.nnxc import NNLDA\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "n_input, n_hidden = 2, 1\n",
    "nnmodel = (nn.Linear(n_input, n_hidden))\n",
    "output = NNLDA(nnmodel)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ad04d58",
   "metadata": {},
   "source": [
    "#### HybridXC layer :\n",
    "\n",
    "The HybridXC module computes XC energy by summing XC energy computed\n",
    "from libxc(any conventional DFT functional) and the trainable neural\n",
    "network with tunable weights. This layer constructs a hybrid functional based on the user's choice of what model is to be used to train the functional. This hybrid functional is a combination of the xc that is trained by a neural network, and a conventional DFT functional. It based on this equation from (Kasim & Vinko, 2021) where $\\alpha$, $\\beta$ are the tunable weights.\n",
    "![](assets/xceqns.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "827e0bf9",
   "metadata": {},
   "source": [
    "### SCF iterations layer \n",
    "\n",
    "\n",
    "In the Kohn-Sham theory, the inclusion of the noninteracting kinetic energy functional results in a set of one-particle equations with KS\n",
    "orbitals as their solutions after functional differentiation. It is a\n",
    "variational approach that determines the lowest energy and the related\n",
    "molecular orbitals and orbital energies by using the electron-electron\n",
    "interaction potential. To learn more about Density Functional Theory\n",
    "and the Kohn-Sham approach please use the references below.\n",
    "\n",
    "The XCNNSCF is used for performing self-consistent iterations. The\n",
    "XC functional in the Kohn-Sham model implementation is replaced by a\n",
    "neural network.\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d2de8866",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(-99.1360, dtype=torch.float64, grad_fn=<AddBackward0>)\n"
     ]
    }
   ],
   "source": [
    "# Example; calculating energy using the scf layer\n",
    "from deepchem.models.dft.scf import XCNNSCF\n",
    "import torch\n",
    "from deepchem.feat.dft_data import DFTEntry, DFTSystem\n",
    "from deepchem.models.dft.nnxc import HybridXC\n",
    "nnmodel = (torch.nn.Sequential(torch.nn.Linear(2, 10),torch.nn.Tanh(),torch.nn.Linear(10, 1))).to(torch.double)\n",
    "hybridxc = HybridXC(\"lda_x\", nnmodel, aweight0=0.0)\n",
    "evl = XCNNSCF(hybridxc, dm_entry_for_HF )\n",
    "system = DFTSystem(systems[0])\n",
    "run = evl.run(system)\n",
    "output = run.energy()\n",
    "print(output)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74e970b2",
   "metadata": {},
   "source": [
    "### Training the XC Model\n",
    "\n",
    "The XCModel class is used to initialize and run Differentiable Quantum Chemistry (i.e, DFT) calculations, using an exchange correlation functional that has been replaced by a neural network. The model parame- ters consist of the PyTorch model used to train the functional and the choice of loss function. The forward method initializes the Neural Network LDA layer (NNXC), and hybridizes the func- tional with a traditional LDA functional. The hybrid xc is used to solve the Kohn-Sham equations. Once the self consistent iterations converge, the total energy of the data point is calculated and used to calculate the loss. The trained model can be used with DeepChem functions such as evaluate and predict with different metrics (Kasim & Vinko, 2021; Ramsundar et al., 2021a)\n",
    "\n",
    "References \n",
    "Kasim, M. and Vinko, S. Learning the exchange-correlation functional from nature with fully differentiable density functional theory. Physical Review Letters, 127(12), sep 2021. doi: 10.1103/physrevlett.127.126403. URL https://doi.org/10.1103%2Fphysrevlett.127.126403.\n",
    "\n",
    "Ramsundar, Peastman, Amacbride, and nvtrang91. Making\n",
    "deepchem a better framework for ai-driven science, Apr\n",
    "2021a. URL https://forum.deepchem.io/t/ making-deepchem-a-better-framework-for-ai-driven- 431.\n",
    "Schematics of the exchange correlation XCModel.\n",
    "\n",
    "![Schematic](assests/DFT.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4d269fb6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Example: training a function using XCModel\n",
    "from deepchem.models.dft.dftxc import XCModel\n",
    "import deepchem as dc\n",
    "import tempfile\n",
    "\n",
    "# create a file to save the model \n",
    "model_dir = tempfile.mkdtemp()\n",
    "\n",
    "# initialise the model \n",
    "model = XCModel(\"lda_x\",\n",
    "                    batch_size=1,\n",
    "                    log_frequency=1,\n",
    "                    mode=\"classification\",\n",
    "                    n_tasks=2,\n",
    "                    model_dir=model_dir)\n",
    "\n",
    "# Calculate the loss on fitting the model \n",
    "loss = model.fit(dataset, nb_epoch=1, checkpoint_interval=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d572faae",
   "metadata": {},
   "source": [
    "### Predicts and evaluation using the XC model \n",
    "\n",
    "The predictions can be run on various different molecules. In this tutorial, we will predict energy values and plot the Hydrogen dissociation curve against CCSD values. \n",
    "\n",
    "Note; the predictions in this example might not be very accurate since we are only training the model on two datapoints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "6f04b00b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# load the datasets\n",
    "import numpy as np\n",
    "inputs = 'assets/h2.yaml'\n",
    "data = DFTYamlLoader()\n",
    "h2_dataset = data.create_dataset(inputs)\n",
    "predict = model.predict(h2_dataset)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "3433e9c0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAk0AAAGwCAYAAAC0HlECAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAA9hAAAPYQGoP6dpAABu2klEQVR4nO3dd3xV9f3H8de92XsPEkLCFmSvCIpKAbFYlVYRV0WrVltxNNYKtT8BtUWts60t1oXWUiduBQMyFJEpMmSvsLJDQvZN7vn9cZKbXDJIIMnNTd7Px+M+yD3j3s83N4EP3/M5n6/FMAwDEREREWmU1dUBiIiIiLgDJU0iIiIiTaCkSURERKQJlDSJiIiINIGSJhEREZEmUNIkIiIi0gRKmkRERESawNPVAbR3drudY8eOERQUhMVicXU4IiIi0gSGYXDy5Eni4uKwWltmjkhJ02kcO3aMhIQEV4chIiIiZ+Dw4cN07dq1RV5LSdNpBAUFAXDgwAHCw8NdHE3Lsq+aijX9SyqHPIVHn9tdHU6LstlsfPnll1xyySV4eXm5OpwWpbG5p448NujY49PY3FNubi7du3d3/DveEpQ0nUb1JbmgoCCCg4NdHE3LqozqjkcBVHrk4tHBxmaz2fD39yc4OLjD/UWgsbmnjjw26Njj09jck81mA2jR0hoVgndmfnEAWEqOujgQERGR9k9JUydm+MWbX5Qcc20gIiIibkBJU2dWlTRppklEROT0lDR1YkbV5TmUNImIiJyWkqbOzM+8BdNiywdboYuDERERad+UNHVmXkHY8DO/1myTiIhIo5Q0dXKllgjzi2IlTSIiIo1R0tTJlVQnTZppEhERaZSSpk6u1FrV5bz4iGsDERERaeeUNHVyJZZI8wtdnhMREWmUkqZOrtRSNdNUopkmERGRxihp6uRUCC4iItI0Spo6ORWCi4iINI2Spk6u1FqdNKWD3ebaYERERNoxJU2dXBnBGBYvwDATJxEREamXkqbOzmKF6jXo1HZARESkQUqaRAv3ioiINIGSJgG/ePNP3UEnIiLSILdLml544QWSkpLw9fUlOTmZdevWNXjsggULsFgsTg9fX982jNY9GNVJk3o1iYiINMitkqa3336blJQUZs+ezaZNmxg8eDCTJk0iMzOzwXOCg4M5fvy443Ho0KE2jNhN+GumSURE5HTcKml65plnuP3227nlllvo378/8+fPx9/fn1dffbXBcywWC7GxsY5HTExMG0bsHgwVgouIiJyWp6sDaKry8nI2btzIrFmzHNusVisTJkxgzZo1DZ5XWFhIYmIidrudYcOG8Ze//IVzzz23wePLysooKytzPC8oKADAZrNhs3WsPkbV46nwisETMIqPUtFBxlg9to72mYHG5q468tigY49PY3NPrTEmi2EYRou/ais4duwY8fHxfPvtt4wePdqx/Q9/+AMrV65k7dq1dc5Zs2YNe/bsYdCgQeTn5/PUU0+xatUqtm/fTteuXet9nzlz5jB37tw62xcuXIi/v3/LDagd8bNncEnJHVTixaf+74DF4uqQREREzkpxcTHXX389+fn5BAcHt8hrduik6VQ2m41+/fpx3XXX8eijj9Z7TH0zTQkJCRw/fpyIiIizH0g7YrPZSE1NZeL4i/D/OMzcdsUx8Il0cWRnzzG2iRPx8vJydTgtSmNzTx15bNCxx6exuaecnBy6dOnSokmT21yei4yMxMPDg4yMDKftGRkZxMbGNuk1vLy8GDp0KHv37m3wGB8fH3x8fOo9t6P9QFXz8gkA32gozcTLlgmBXVwdUovp0J+bxuaWOvLYoGOPT2NzL60xHrcpBPf29mb48OEsW7bMsc1ut7Ns2TKnmafGVFZWsnXrVrp06ThJwZkqr7Cz4VAem3OqLsU5ejWpGFxERKQ+bjPTBJCSksL06dMZMWIEo0aN4rnnnqOoqIhbbrkFgJtuuon4+HjmzZsHwCOPPMJ5551Hr169OHHiBH/96185dOgQt912myuH0S6U2Cq57uX1gAcptkq8/OIh73t1BRcREWmAWyVN06ZNIysri4cffpj09HSGDBnC4sWLHW0E0tLSsFprJs/y8vK4/fbbSU9PJywsjOHDh/Ptt9/Sv39/Vw2h3Qj29cTPy0qJzU5GQRlB/lWF8erVJCIiUi+3SpoAZsyYwYwZM+rdt2LFCqfnzz77LM8++2wbROV+LBYLscG+HMgpJr2glF7+ujwnIiLSGLepaZKWFxtiLimTXlAG1TNNujwnIiJSLyVNnVhssHmXYHp+qQrBRURETkNJUycWE2zONGUUlGr9ORERkdNQ0tSJOWaaal+es52AiiLXBSUiItJOKWnqxGJrzzR5BYNnoLlDs00iIiJ1KGnqxKovz6UXVC0bU32JTsXgIiIidShp6sRiQ8zLc1mFZdgq7eCnXk0iIiINUdLUiYX7e+NhMTAMyDpZVqsYXHfQiYiInEpJUydmtVoI8Ta/Pp5fql5NIiIijVDS1MlVJ03q1SQiItI4JU2dXKi3AcDx/BL1ahIREWmEkqZOLrRqpslscKnLcyIiIg1R0tTJhThmmmpdnitNB3uFC6MSERFpf5Q0dXKhZtcBs6bJNxosnmDYzcRJREREHJQ0dXLVNU3pBaVgsYJfnLlDxeAiIiJOlDR1crVrmux2Q8XgIiIiDVDS1MkFe4HFArZKg5yichWDi4iINEBJUyfnYYWoQLOwSb2aREREGqakSYgNrkqaarcd0OU5ERERJ0qahJhgXwDS80tqZppKNNMkIiJSm5Imccw0mevPqRBcRESkPkqapGam6dSu4IbhwqhERETaFyVNQmxI9eW50po+TZWlUJ7rwqhERETaFyVNUlMInl8KHj7gE2Xu0CU6ERERByVNQmzV5bnj+aUYRu0GlyoGFxERqaakSYipmmkqsVVSUFpR6w46zTSJiIhUU9Ik+Hp5EOrvBVRdolOvJhERkTqUNAlQ+xKdejWJiIjUR0mTANCl6g66DHUFFxERqZeSJgEgNsQPOLXBpWaaREREqilpEqDm8pzTor0qBBcREXFQ0iRAzeW547ULwcvzoKLYhVGJiIi0H0qaBKjpCp5RUApeweAZYO5QXZOIiAigpEmqOM00WSzOa9CJiIiIkiYxxVQlTfklNkrKK2vqmlQMLiIiAihpkipBPp4EeHsAkF6gYnAREZFTKWkSACwWi6Ou6Xh+iXo1iYiInEJJkzhUJ03p6tUkIiJSh9slTS+88AJJSUn4+vqSnJzMunXrmnTeW2+9hcViYcqUKa0boBuLDa7d4FKF4CIiIrW5VdL09ttvk5KSwuzZs9m0aRODBw9m0qRJZGZmNnrewYMH+f3vf8/YsWPbKFL35LSUiqMQXEmTiIgIuFnS9Mwzz3D77bdzyy230L9/f+bPn4+/vz+vvvpqg+dUVlZyww03MHfuXHr06NGG0bqfWKcGl1VJU+lxsFe4MCoREZH2wdPVATRVeXk5GzduZNasWY5tVquVCRMmsGbNmgbPe+SRR4iOjubWW2/l66+/Pu37lJWVUVZW5nheUFAAgM1mw2azncUI2p/q8VT/GRlg/jgcP1GCzSMMT4snFqMCW+GRmpknN3Hq2DoSjc09deSxQccen8bmnlpjTG6TNGVnZ1NZWUlMTIzT9piYGHbu3FnvOd988w2vvPIKmzdvbvL7zJs3j7lz59bZvnz5cvz9/ZsVs7tITU0F4EgRgCdpWfl8/sUSJhKKP9msWfoueR59XBrjmaoeW0eksbmnjjw26Njj09jcS3Fxyy8D5jZJU3OdPHmSX/7yl7z00ktERkY2+bxZs2aRkpLieF5QUEBCQgLjxo0jIiKiNUJ1GZvNRmpqKhMnTsTLy4uconL+umUFJyssTLjkUnxX9oTcbMYMTcToOtnV4TbLqWPrSDQ299SRxwYde3wam3vKyclp8dd0m6QpMjISDw8PMjIynLZnZGQQGxtb5/h9+/Zx8OBBLr/8csc2u90OgKenJ7t27aJnz551zvPx8cHHx6fOdi8vrw73A1WtemwxIZ54e1gpr7STV1pJQEAC5K7FszwD3HTsneFz64g0NvfVkcensbmX1hiP2xSCe3t7M3z4cJYtW+bYZrfbWbZsGaNHj65z/DnnnMPWrVvZvHmz43HFFVcwbtw4Nm/eTEJCQluG7xYsFgsxIWbCqF5NIiIiztxmpgkgJSWF6dOnM2LECEaNGsVzzz1HUVERt9xyCwA33XQT8fHxzJs3D19fXwYMGOB0fmhoKECd7VKjS7Afh3NLzKVU1KtJRETEwa2SpmnTppGVlcXDDz9Meno6Q4YMYfHixY7i8LS0NKxWt5k8a5ecuoInaKZJRESkmlslTQAzZsxgxowZ9e5bsWJFo+cuWLCg5QPqYJx6NfVVg0sREZFqmpYRJ7HBVTNNp16eMwwXRiUiIuJ6SprESZfal+f84syNlSVQnufCqERERFxPSZM4iamdNHn4gk9VjysVg4uISCenpEmc1F601243ai3cq2JwERHp3JQ0iZOoQB+sFqiwG2QXldXq1aSZJhER6dyUNIkTTw8r0UG1LtGpV5OIiAigpEnqEVO77YAuz4mIiABKmqQeXYJr6pocM026PCciIp2ckiapI7a+maYSzTSJiEjnpqRJ6nBaSkWF4CIiIoCSJqlHF8dMU0nN5bnyXKgocWFUIiIirqWkSeqIddQ0lYFXCHj4mzt0B52IiHRiSpqkji4hfoA502SAisFFRERQ0iT1iA72AaDUZie/xFarrknF4CIi0nkpaZI6fL08CA/wBiC9oPYddJppEhGRzktJk9Sruq7peL56NYmIiICSJmmAU9sB9WoSERFR0iT1c2pwqZkmERERJU1SP8dSKk4NLjXTJCIinZeSJqmXY6apdiF4aTrYK10YlYiIiOsoaZJ61dQ0lYBvDFg8wKiE0gwXRyYiIuIaSpqkXl1qF4JbPcCvi7lDl+hERKSTUtIk9Yqt6gpeUFpBUVkF+FUVg6tXk4iIdFJKmqRegT6eBPp4AlUNLh3F4EqaRESkc1LSJA1SryYREZEaSpqkQU51TerVJCIinZySJmlQ9VIqzpfnNNMkIiKdk5ImaVBNV/ASLdorIiKdnpImaVBNTVOZ8+U5w3BhVCIiIq6hpEka5KhpKigBvzhzY2Ux2E64LigREREXUdIkDYoJrlUI7ukHPhHmDhWDi4hIJ6SkSRrUparBZXZhOWUVlTV1TSoGFxGRTkhJkzQozN8Lb0/zRySzoEzF4CIi0qkpaZIGWSyWWnVN6tUkIiKdm5ImaVR1XdPxfPVqEhGRzk1JkzSqeqYpo3ZXcF2eExGRTkhJkzSqpsFlqQrBRUSkU1PSJI2qWUqlpObynGaaRESkE1LSJI3qUnumqfryXFkOVJa6MCoREZG253ZJ0wsvvEBSUhK+vr4kJyezbt26Bo9dtGgRI0aMIDQ0lICAAIYMGcJ//vOfNozW/cVW9WrKyC8Fr1DwMJ/rDjoREels3Cppevvtt0lJSWH27Nls2rSJwYMHM2nSJDIzM+s9Pjw8nIceeog1a9awZcsWbrnlFm655RaWLFnSxpG7L0ch+MkyKg1UDC4iIp2Wp6sDaI5nnnmG22+/nVtuuQWA+fPn89lnn/Hqq68yc+bMOsdffPHFTs/vvfdeXn/9db755hsmTZpU73uUlZVRVlbmeF5QUACAzWbDZrO10Ejah+rxNDauEB8rHlYLlXaD43mFxPnGYT25h4qTBzHCRrdVqM3WlLG5K43NPXXksUHHHp/G5p5aY0wWw3CPJevLy8vx9/fnvffeY8qUKY7t06dP58SJE3z00UeNnm8YBl999RVXXHEFH374IRMnTqz3uDlz5jB37tw62xcuXIi/v/9ZjcFdzd7owYlyCykDK/i557MkVK5ku9d09nr/3NWhiYiI1Ku4uJjrr7+e/Px8goODW+Q13WamKTs7m8rKSmJiYpy2x8TEsHPnzgbPy8/PJz4+nrKyMjw8PPjnP//ZYMIEMGvWLFJSUhzPCwoKSEhIYNy4cURERJz9QNoRm81GamoqEydOxMvLq8HjXjuyls2H8+k5YDhxFSNh10rOSQqmz5DJbRht8zR1bO5IY3NPHXls0LHHp7G5p5ycnBZ/zbNKmkpLS/H19W2pWFpFUFAQmzdvprCwkGXLlpGSkkKPHj3qXLqr5uPjg4+PT53tXl5eHe4HqtrpxtYlxI/Nh/PJKrThEdkNAI/SY3i4wfejM39u7kxjc18deXwam3tpjfE0uxDcbrfz6KOPEh8fT2BgIPv37wfg//7v/3jllVdaPMBqkZGReHh4kJGR4bQ9IyOD2NjYBs+zWq306tWLIUOGcP/993P11Vczb968VouzI3I0uNT6cyIi0ok1O2l67LHHWLBgAU8++STe3t6O7QMGDODll19u0eBq8/b2Zvjw4SxbtsyxzW63s2zZMkaPbnpBst1udyr0ltNzWkqluit4ibqCi4hI59Lsy3NvvPEG//73vxk/fjx33nmnY/vgwYMbrS1qCSkpKUyfPp0RI0YwatQonnvuOYqKihx30910003Ex8c7ZpLmzZvHiBEj6NmzJ2VlZXz++ef85z//4V//+lerxtnRVPdqMhtcmpfnKDkO9kqwergwMhERkbbT7KTp6NGj9OrVq852u93e6rcsTps2jaysLB5++GHS09MZMmQIixcvdhSHp6WlYbXWTJ4VFRXx29/+liNHjuDn58c555zDm2++ybRp01o1zo6mZimVUvCNBYsHGJVQlgl+XVwcnYiISNtodtLUv39/vv76axITE522v/feewwdOrTFAmvIjBkzmDFjRr37VqxY4fT8scce47HHHmv1mDq66stz6fmlGBYrFt9Ys7ll8RElTSIi0mk0O2l6+OGHmT59OkePHsVut7No0SJ27drFG2+8waefftoaMYqLRQebdxOWVdg5UWwjzL9rVdJ0FCJGujg6ERGRttHsQvArr7ySTz75hKVLlxIQEMDDDz/Mjh07+OSTTxrtfyTuy8fTg4gAs+jfrGuqKgYvVjG4iIh0HmfUp2ns2LGkpqa2dCzSjsWG+JJTVE56QQn9HXfQqe2AiIh0Hme0YO+JEyd4+eWX+eMf/0hubi4AmzZt4uhR/SPaUdXUNZWpV5OIiHRKzZ5p2rJlCxMmTCAkJISDBw9y2223ER4ezqJFi0hLS+ONN95ojTjFxWIdSVMJRKtXk4iIdD7NnmlKSUnh5ptvZs+ePU5LqEyePJlVq1a1aHDSflS3HTBrmjTTJCIinU+zk6b169dzxx131NkeHx9Penp6iwQl7U91g8v0glqF4CVHwTBcGJWIiEjbaXbS5OPjQ0FBQZ3tu3fvJioqqkWCkvandq8mx1IqFUVgy3dhVCIiIm2n2UnTFVdcwSOPPOLo/m2xWEhLS+PBBx/kqquuavEApX2ICa6VNHn6gXe4uUOX6EREpJNodtL09NNPU1hYSHR0NCUlJVx00UX06tWLoKAg/vznP7dGjNIOVBeCnyyroLCsQr2aRESk02n23XMhISGkpqayevVqfvjhBwoLCxk2bBgTJkxojfiknQj08STI15OTpRWk55fSy68rnNiqXk0iItJpNCtpstls+Pn5sXnzZs4//3zOP//81opL2qEuIb6cLC00kybHTJOSJhER6RyadXnOy8uLbt26UVlZ2VrxSDsW42g7UFJTDK5eTSIi0kk0u6bpoYcecuoELp1H9R10GQXq1SQiIp1Ps2ua/vGPf7B3717i4uJITEwkICDAaf+mTZtaLDhpX6p7NWnRXhER6YyanTRdeeWVWCyW1ohF2rnY4Hp6NakQXEREOolmJ01z5sxphTDEHVRfnjNnmnqaG8uyobIUPHwbOVNERMT9NbumqUePHuTk5NTZfuLECXr06NEiQUn7FFu7psk7rCZRKjnmwqhERETaRrOTpoMHD9Z791xZWRlHjqi+pSOrnmnKKSqntMIOfioGFxGRzqPJl+c+/vhjx9dLliwhJCTE8byyspJly5bRvXv3lo1O2pUQPy98PK2UVdjJLCijm388FO5VMbiIiHQKTU6apkyZ4vh6+vTpTvu8vLxISkri6aefbrHApP2xWCx0CfHlYE4x6QWldFMxuIiIdCJNTprsdjsA3bt3Z8OGDURERLRaUNJ+xVYlTcfzS9SrSUREOpVm1TTZbDZ69OihxpadmFPbAfVqEhGRTqTZy6hs2bKltWIRN+Dc4LJqpkmX50REpBNo9t1zN954I6+88kprxCJuwGkpFT/NNImISOfR7OaWFRUVvPrqqyxdupThw4fXWUblmWeeabHgpP2JdWpwmWhuLDkOhh0szc7BRURE3Eazk6Zt27YxbNgwAHbv3u20T8urdHxONU2+sWaiZFRAaSb4xbo4OhERkdbT7KRp+fLlrRGHuInqy3NZhWVUGFY8fWPNjuDFR5Q0iYhIh6brKdIsEYE+eFotVNoNsgvLVQwuIiKdRrNnmgA2bNjAO++8Q1paGuXl5U77Fi1a1CKBSfvkYbUQHeTDsfxSjueXEKticBER6SSaPdP01ltvMWbMGHbs2MEHH3yAzWZj+/btfPXVV05Lq0jHVV0M7tyrSTNNIiLSsTU7afrLX/7Cs88+yyeffIK3tzfPP/88O3fu5JprrqFbt26tEaO0M12qejWlF6hXk4iIdB7NTpr27dvHZZddBoC3tzdFRUVYLBZ+97vf8e9//7vFA5T2x2mmSZfnRESkk2h20hQWFsbJkycBiI+PZ9u2bQCcOHGC4uLilo1O2qXqtgPqCi4iIp1JswvBL7zwQlJTUxk4cCBTp07l3nvv5auvviI1NZXx48e3RozSzjhmmk7tCm4YoF5dIiLSQTU7afrHP/5BaWkpAA899BBeXl58++23XHXVVfzpT39q8QCl/elSXyF4RRHYCsBbNwOIiEjH1OykKTw83PG11Wpl5syZLRqQtH8xtbqCGx5+WLzDoDzPvESnpElERDqoJidNBQUFTTouODj4jIMR91CdNJVX2sktKifCL95MmoqPQEh/F0cnIiLSOppcCB4aGkpYWFiDj+r9re2FF14gKSkJX19fkpOTWbduXYPHvvTSS4wdO9YR44QJExo9XprG29NKZKAPcErbAfVqEhGRDqzJM02115wzDIPJkyfz8ssvEx8f3yqB1eftt98mJSWF+fPnk5yczHPPPcekSZPYtWsX0dHRdY5fsWIF1113HWPGjMHX15cnnniCSy65hO3bt7dp3B1RlxBfsgvLSM8v5dzquibdQSciIh1Yk5Omiy66yOm5h4cH5513Hj169GjxoBryzDPPcPvtt3PLLbcAMH/+fD777DNeffXVemur/vvf/zo9f/nll3n//fdZtmwZN910U5vE3FHFBPuy9Wh+VdsB9WoSEZGO74zWnnOF8vJyNm7cyKxZsxzbrFYrEyZMYM2aNU16jeLiYmw2m1Mx+6nKysooKytzPK+u5bLZbNhstjOMvn2qHs+ZjCsmyBuAY3nFVIR1wROwFx2msp18j85mbO2dxuaeOvLYoGOPT2NzT60xJrdJmrKzs6msrCQmJsZpe0xMDDt37mzSazz44IPExcUxYcKEBo+ZN28ec+fOrbN9+fLl+Pv7Ny9oN5Gamtrsc/LTLYAHG37cy/rio4wGCjJ2sPLzz1s8vrNxJmNzFxqbe+rIY4OOPT6Nzb20RsPts0qaLG7UyPDxxx/nrbfeYsWKFfj6+jZ43KxZs0hJSXE8LygoICEhgXHjxhEREdEWobYZm81GamoqEydOxMvLq1nnln1/jE/TtuEZHMmIC6dA6mOEeBUyefLk1gm2mc5mbO2dxuaeOvLYoGOPT2NzTzk5OS3+mk1Omn7xi184PS8tLeXOO+8kICDAafuiRYtaJrJTREZG4uHhQUZGhtP2jIwMYmNjGz33qaee4vHHH2fp0qUMGjSo0WN9fHzw8fGps93Ly6vD/UBVO5OxdQ03P/eMgjK8gvsAYCnLwstqB4+63z9X0efmnjQ299WRx6exuZfWGE+TWw6EhIQ4PW688Ubi4uLqbG8t3t7eDB8+nGXLljm22e12li1bxujRoxs878knn+TRRx9l8eLFjBgxotXi62yql1LJKCgD73CwViVKJcdcGJWIiEjrafJM02uvvdaacTRJSkoK06dPZ8SIEYwaNYrnnnuOoqIix910N910E/Hx8cybNw+AJ554gocffpiFCxeSlJREeno6AIGBgQQGBrpsHB1BddJUWFbBybIKgvy7QuE+s1dTYHcXRyciItLy3KYQHGDatGlkZWXx8MMPk56ezpAhQ1i8eLGjODwtLQ2rtWby7F//+hfl5eVcffXVTq8ze/Zs5syZ05ahdzj+3p4E+3pSUFpBen4pQf7xVUmT2g6IiEjH5FZJE8CMGTOYMWNGvftWrFjh9PzgwYOtH1An1iXEj4LSk6QXlNLbTw0uRUSkY2tyTZPIqaov0ZkNLrWUioiIdGxKmuSMxVYt3JueXwqOmSZdnhMRkY5JSZOcMc00iYhIZ3JGNU179uxh+fLlZGZmYrfbnfY9/PDDLRKYtH9dHG0HtP6ciIh0fM1Oml566SV+85vfEBkZSWxsrFNXcIvFoqSpE3GaafJLMjeWHAPDDhZNYoqISMfS7KTpscce489//jMPPvhga8QjbqQ6aUrPLwG/WDNRMiqgNAv8Yk5ztoiIiHtp9nRAXl4eU6dObY1YxM10CfYDIK/YRmmlFXyrEiUVg4uISAfU7KRp6tSpfPnll60Ri7iZYD9P/Lw8gKq6Jr/qYnAlTSIi0vE0+/Jcr169+L//+z++++47Bg4cWGdBvHvuuafFgpP2zWKxEBviy4HsIo7nl5IY3Ady10Pu99D1SleHJyIi0qKanTT9+9//JjAwkJUrV7Jy5UqnfRaLRUlTJxMbbCZN6fmlEHUBHPwvZH3t6rBERERaXLOTpgMHDrRGHOKmqtsOpBeUQo8LzY3Z34HdBlavRs4UERFxL7ovXM5KzR10pRDcD3wioLIYcje5ODIREZGW1aSZppSUFB599FECAgJISUlp9NhnnnmmRQIT91DTq6kELBbzEt2RjyBzFUQmuzg6ERGRltOkpOn777/HZrM5vm5I7UaX0jk41p8rKDM3RI01k6asr4EHXBeYiIhIC2tS0rR8+fJ6vxbpEmL2akrPLzE3RFfVNWV9o87gIiLSoehfNDkrMSE+AGSeLMNWaYewoeAZAOV5kL/dxdGJiIi0HCVNclYiA3zwtFowDMg6WQZWT4gcbe7MVOsBERHpOJQ0yVmxWi3EBNdqOwBmXROoX5OIiHQoSprkrHWp3XYAauqaMr8Gw3BRVCIiIi2r2UlTUVFRa8QhbizG0XagKmmKSDYbW5YchSI1QxURkY6h2UlTTEwMv/rVr/jmm29aIx5xQ12qLs9lVF+e8/SD8BHm16prEhGRDqLZSdObb75Jbm4uP/nJT+jTpw+PP/44x44da43YxE3EnjrTBKprEhGRDqfZSdOUKVP48MMPOXr0KHfeeScLFy4kMTGRn/3sZyxatIiKiorWiFPasZqlVEpqNjrqmla5ICIREZGWd8aF4FFRUaSkpLBlyxaeeeYZli5dytVXX01cXBwPP/wwxcXFLRmntGNd6p1pOh+wwMk9UJLumsBERERa0BknTRkZGTz55JP079+fmTNncvXVV7Ns2TKefvppFi1axJQpU1owTGnPYqu6gmcWlGG3V90t5x0KoQPNr7NU/yYiIu6vScuo1LZo0SJee+01lixZQv/+/fntb3/LjTfeSGhoqOOYMWPG0K9fv5aMU9qx6CAfLBYor7STW1xOZKBP1Y4L4cQWsxi829WuDVJEROQsNXum6ZZbbiEuLo7Vq1ezefNmZsyY4ZQwAcTFxfHQQw+1VIzSznl5WB2JUnq9xeCqaxIREffX7Jmm48eP4+/v3+gxfn5+zJ49+4yDEvfTJcSXrJNlpOeXMiA+xNwYXZU05f0A5fngHeK6AEVERM5Ss2eaKioqKCgoqPM4efIk5eXlrRGjuIHYql5NxwtqzTT5dYHAnoAB2d+6JjAREZEW0uykKTQ0lLCwsDqP0NBQ/Pz8SExMZPbs2djt9taIV9qpetsOgFoPiIhIh9Hsy3MLFizgoYce4uabb2bUqFEArFu3jtdff50//elPZGVl8dRTT+Hj48Mf//jHFg9Y2qd6G1yCWde0/zU1uRQREbfX7KTp9ddf5+mnn+aaa65xbLv88ssZOHAgL774IsuWLaNbt278+c9/VtLUiVT3asooOCVpqq5rylkPlaXg4dvGkYmIiLSMZl+e+/bbbxk6dGid7UOHDmXNmjUAXHDBBaSlpZ19dOI2YoPNXk11ZpoCe4JvLNjLIWedCyITERFpGc1OmhISEnjllVfqbH/llVdISEgAICcnh7CwsLOPTtxGTU1TKYZh1OywWFTXJCIiHUKzL8899dRTTJ06lS+++IKRI0cCsGHDBnbu3Ml7770HwPr165k2bVrLRirtWvXdc8XllZwsqyDY16tmZ9RYSHvHbHIpIiLippqdNF1xxRXs2rWLF198kV27dgHw05/+lA8//JCkpCQAfvOb37RokNL++Xl7EOrvxYliG+n5pc5JU3VdU/a3YK8Aa7N/7ERERFyuWf962Ww2Lr30UubPn8+8efNaKyZxU7HBvpwotnE8v5Q+MUE1O0IGgFco2E5A3maIGOGiCEVERM5cs2qavLy82LJlS2vFIm6ua5jZKX5PxknnHVYPiDrf/FqtB0RExE01uxD8xhtvrLcQvK288MILJCUl4evrS3JyMuvWNXxH1vbt27nqqqtISkrCYrHw3HPPtV2gndCIJLP4f+2B3Lo7qy/Rqa5JRETcVLOLSyoqKnj11VdZunQpw4cPJyAgwGn/M88802LBnertt98mJSWF+fPnk5yczHPPPcekSZPYtWsX0dHRdY4vLi6mR48eTJ06ld/97netFpeYkruHA7D+YC52u4HVaqnZ6Vi892swDPOuOhERETfS7KRp27ZtDBs2DIDdu3c77bO08j+EzzzzDLfffju33HILAPPnz+ezzz7j1VdfZebMmXWOHzlypOMOv/r2S8saEB+Cv7cHJ4pt7Mo4Sb8uwTU7w0eYjS3LsqFgJ4T0c12gIiIiZ6DZSdPy5ctbI47TKi8vZ+PGjcyaNcuxzWq1MmHCBEdTzZZQVlZGWVmZ43lBQQFgFsHbbLYWe5/2oHo8LTmu4d1C+XpvDqv3ZNIr0q/WHgse4clYs1ZSkb4Cw79Xi71nfVpjbO2FxuaeOvLYoGOPT2NzT60xpjO+93vv3r3s27ePCy+8ED8/PwzDaNWZpuzsbCorK4mJiXHaHhMTw86dO1vsfebNm8fcuXPrbF++fDn+/v4t9j7tSWpqaou9Vki5BfDg4+92EJW33WnfOeUx9AWOb36bTTvjWuw9G9OSY2tvNDb31JHHBh17fBqbeykuLm7x12x20pSTk8M111zD8uXLsVgs7Nmzhx49enDrrbcSFhbG008/3eJBtqVZs2aRkpLieF5QUEBCQgLjxo0jIiLChZG1PJvNRmpqKhMnTsTLy+v0JzRBbNoJPn1pHYdLffjpTy92SqQtGd6w6h26+hwgdvLkFnm/hrTG2NoLjc09deSxQccen8bmnnJyclr8NZudNP3ud7/Dy8uLtLQ0+vWrqUuZNm0aKSkprZY0RUZG4uHhQUZGhtP2jIwMYmNjW+x9fHx88PHxqbPdy8urw/1AVWvJsQ1NjMDXy0pesY2DeWXO/ZpixoLFA0txGl7lxyGgW4u8Z2P0ubknjc19deTxaWzupTXG0+yWA19++SVPPPEEXbt2ddreu3dvDh061GKBncrb25vhw4ezbNkyxza73c6yZcsYPXp0q72vNI+3p5XhiVWtB/afkuV7BUKYeROBWg+IiIi7aXbSVFRUVG9tT25ubr0zNC0pJSWFl156iddff50dO3bwm9/8hqKiIsfddDfddJNToXh5eTmbN29m8+bNlJeXc/ToUTZv3szevXtbNc7O7rzu5mXM7xrr16QmlyIi4maanTSNHTuWN954w/HcYrFgt9t58sknGTduXIsGd6pp06bx1FNP8fDDDzNkyBA2b97M4sWLHcXhaWlpHD9+3HH8sWPHGDp0KEOHDuX48eM89dRTDB06lNtuu61V4+zsknuYSdPa/TkYhuG8s7pfU+aqNo5KRETk7DS7punJJ59k/PjxbNiwgfLycv7whz+wfft2cnNzWb16dWvE6GTGjBnMmDGj3n0rVqxwep6UlFT3H21pdYMTQvDxtJJdWM6+rCJ6RQfW7Iy6wPyzYAeUZoNvpGuCFBERaaZmzzQNGDCA3bt3c8EFF3DllVdSVFTEL37xC77//nt69uzZGjGKm/Hx9GBot1AA1h44pa7JNxJC+ptfZ33TtoGJiIichTPq0xQSEsJDDz3U0rFIB5LcPYLv9ueydn8uNyQnOu+MGgv5P5qX6BKmuCQ+ERGR5jqjpOnEiROsW7eOzMxM7Ha7076bbrqpRQIT95bcIxyWmTNNdRqfRl8Ie19UMbiIiLiVZidNn3zyCTfccAOFhYUEBwc7Ny+0WJQ0CQDDuoXh7WElo6CMgznFdI+stbBzdTF43vdgKzRbEYiIiLRzza5puv/++/nVr35FYWEhJ06cIC8vz/HIza3nFnPplHy9PBiSEArU068pIAECEsGohOyWWzdQRESkNTU7aTp69Cj33HNPh12HTVpOco9wANbW169JrQdERMTNNDtpmjRpEhs2bGiNWKSDSe7eSL+m6AvNP1XXJCIibqLZNU2XXXYZDzzwAD/++CMDBw6ss7bLFVdc0WLBiXsblhiKp9XCsfxSjuSVkBBea3ayeqYpZy1UloFH63aTFxEROVvNTppuv/12AB555JE6+ywWC5WVlWcflXQI/t6eDE4IZeOhPNbsz3FOmoL7gk8UlGVB7gaIOt91gYqIiDRBsy/P2e32Bh9KmORUyd2r6pr2n1LXZLHUdAfX4r0iIuIGmp00iTSHYx26UzuDg+qaRETErTQ5aZo8eTL5+fmO548//jgnTpxwPM/JyaF///4tGpy4v+GJYXhYLRzJK+HoiRLnndFVdU1Zq8GuWUoREWnfmpw0LVmyhLKyMsfzv/zlL059mSoqKti1a1fLRiduL9DHkwHxIUA9/ZpCB4NnINjyIX+rC6ITERFpuiYnTafeMl7nFnKRBpzXo4G6JqsnRI4xv1Zdk4iItHOqaZJWd15Vv6bvVNckIiJurMlJk8VicV50tWqbyOmMSArDaoFDOcWk55c674yu1Rlcs5ciItKONblPk2EY3Hzzzfj4mE0IS0tLufPOOwkIMBdirV3vJFJbkK8X58aFsPVoPmsP5HDlkPianRGjwOoNpRlwci8E93ZdoCIiIo1octI0ffp0p+c33nhjnWNuuumms49IOqTk7uFsPZrPd/tznZMmD18zccr6xrxEp6RJRETaqSYnTa+99lprxiEdXHKPCF7+5kD9/ZqixtYkTT1/1fbBiYiINIEKwaVNjEoKx2KB/VlFZBY0UtckIiLSTilpkjYR4u9Fv9hgANYeOKX1QOQYwAKF+6H4WNsHJyIi0gRKmqTNJFf3azr1Ep13CIQNMb9W6wEREWmnlDRJm0mu6tdUp8klmHVNoEt0IiLSbilpkjYzqrs507Qns5CcwlNaVDjWodNMk4iItE9KmqTNhAd4c05sEADrTq1rqp5pOrENyvPaODIREZHTU9IkbSq5arbpu1MX7/WLgaA+gAFZq9s+MBERkdNQ0iRtKrlHVV3TqTNNoNYDIiLSrilpkjZVXde0M/0keUXlzjsdxeCqaxIRaTWGYbZ4OfQO1i0z6VP+jqsjchtN7ggu0hIiA33oFR3I3sxC1h3MZdK5sTU7q2eacjdARTF4+rsmSBGRjsIwoPiI+fdq7gbIWW/+WVU76gEkWGIbfw1xUNIkbS65ezh7MwtZu/+UpCmgO/jFQ8lRyP4OYn/iuiBFRNxRyXHI2VCTJOVugNLMusdZvSB0MJWhw9hzxIsBhtH2sbohJU3S5s7rEcF/16bVLQa3WMzZpkNvma0HlDSJiDSsNAtyN9aaRdpg/qfzVBYPCB0I4SPMR8QICBkAHj7YbTbSMj5ngMXS9vG7ISVN0uaqO4PvSC8gv9hGiL9Xzc6oqqRJdU0iIjUqisxLa9nf1SRJRYfqHmexQnB/MzGqTpJCB4GnX9vH3AEpaZI2Fx3kS4/IAPZnF7H+YC4T+sfU2nmh+Wf2GrDbzClkEZHOxDCg6ABkfWv+XZi9Bk5sAaOy7rHBfWuSo/ARED4UPAPaPuZOQkmTuERyj3D2Zxex9kCOc9IU0h+8w8wixdxNEJnsuiBFRNpCRbE5c1SdIGWvqb8Oyb8rRI6GiFFmghQ21Fy7U9qMkiZxieTuEfxv3eG6/ZosVoi6AI5+YtY1KWkSkY7EMMzLao4E6VvI+wGMCufjrF4QNgwix0DUaDNZ8u/qmpjFQUmTuER1XdO2o/mcLLUR5HtKXdPRT8y6pn6/d1GEIiItoKLELNZ2mkVKr3ucXxczQYqsSpDCh4GHb9vHK41S0iQu0SXEj8QIfw7lFLPhYB7jzomu2Vld15T1NRh2c/ZJRMQd2Aog8xvIWgUZKyFvo1mfWZvF07y0Vp0gRY0G/27mHcTSrilpEpdJ7h7OoZxivjuQ45w0hQ8DD3+zrin/Rwgd4LogRUQaU5YDWd+YCVLWKsj73vzPXm2+MTUJUuRosx5Jd7O5JSVN4jLJ3SN4Z8MR1u4/pa7J6gWR50HGV+Zsk5ImEWkvSjJqZpGyVsGJrXWPCexpzphHX2T2ngvorlmkDsLtrnu88MILJCUl4evrS3JyMuvWrWv0+HfffZdzzjkHX19fBg4cyOeff95GkcrpVNc1bT2aT1HZKUWQWodORNqD4iNYDi1kcNk/8Vw8AD6IhW+ugT0v1CRMwf2g1x0wZiFMOQxX7IXzXoUe0yGwhxKmDsStZprefvttUlJSmD9/PsnJyTz33HNMmjSJXbt2ER0dXef4b7/9luuuu4558+bxs5/9jIULFzJlyhQ2bdrEgAGavXC1rmH+dA3z40heCRsP5XFhn6iandV1TZmrzLtN9JeOiLS26v5Imasgc6X5Z+F+PIEkgJMAFrNZZO2ZJN+6//5Ix+RWSdMzzzzD7bffzi233ALA/Pnz+eyzz3j11VeZOXNmneOff/55Lr30Uh544AEAHn30UVJTU/nHP/7B/Pnz632PsrIyysrKHM8LCgoAsNls2Gy2es9xV9XjceW4RiaFcSSvhG/3ZjG6e2jNjpDheFo8sZQcxZa/x5zebob2MLbWorG5p448NnDj8ZVmYMn8CmvGV1gyvsJScthpt4EVe+gQDhQmkDD8RqyxY8E73Pk13G3Mtbjt59YErTEmi2G4xyp95eXl+Pv789577zFlyhTH9unTp3PixAk++uijOud069aNlJQU7rvvPse22bNn8+GHH/LDDz/U+z5z5sxh7ty5dbYvXLgQf3//sx6HOPsu08L/9nnQPcjgvgHO3W7HlvyBcPtuNnnfy2GvcS6KUEQ6Eg+jhIjK7URVbiGq8gdCDOelSOx4kmftRY7HueRYzyXXox8VFhVtu6Pi4mKuv/568vPzCQ4ObpHXdJuZpuzsbCorK4mJiXHaHhMTw86dO+s9Jz09vd7j09Pr6ZFRZdasWaSkpDieFxQUkJCQwLhx44iIiDiLEbQ/NpuN1NRUJk6ciJeXa5YrGZBbzP+e/YYjxVbGTZiAn7eHY591yyrY9QxDYjMYmDy5Wa/bHsbWWjQ299SRxwbteHz2Cix5G7BkLDNnknK+w2LUzEAYWCB0CPaYn2DEjMeIGEOwpz/BQPX8drsdWwvoyGPLyck5/UHN5DZJU1vx8fHBx8enznYvL68O9wNVzZVj6xEdTJcQX47nl7L1eCHn94qs2Zl4Dex6Buvhd7EOegSCezf79fW5uSeNzX25fHyGAQU7IX2p+chcYfZOqi0gCWInQuwELDE/Ad9IPOp7rVO4fGytqCOOrTXG4zZJU2RkJB4eHmRkZDhtz8jIIDY2tt5zYmNjm3W8tD2LxUJy93A+3HyMtftznJOmyGSImwzHPodtc2HMm64LVETar5LjNUlS+lIoOea83zscYsdD7ATzEdjDNXGK23OblgPe3t4MHz6cZcuWObbZ7XaWLVvG6NGj6z1n9OjRTscDpKamNni8uMZ5PczLnt+dug4dwKBHzD8PLjQbXYqIVJTAscWw8T74bAB8EAdrboIDb5gJk9XHTI6GPA6XboBfZMIF70CvXythkrPiNjNNACkpKUyfPp0RI0YwatQonnvuOYqKihx30910003Ex8czb948AO69914uuuginn76aS677DLeeustNmzYwL///W9XDkNOkVyVNG1OO0GprRJfr1oT5eHDIeEXcHgRbJkNY991UZQi4lKFB+DYF+bMc8ZXUFlSa6fF/LuieiYpcow6bjdBcXkFR3OLOFbs6kjch1slTdOmTSMrK4uHH36Y9PR0hgwZwuLFix3F3mlpaVitNZNnY8aMYeHChfzpT3/ij3/8I7179+bDDz9Uj6Z2JinCn+ggHzJPlvF92glG9zyl4H7gXDj8ARx+D/I2Q9gQV4QpIm2pstxcEeDY5+aj4JQbfvziIe6n0GUSxIwDn451o87ZsFXayTpZRkZBadWjjHTH1+bzjPxSTlY1Fe4a4MFtLo7ZXbhV0gQwY8YMZsyYUe++FStW1Nk2depUpk6d2spRydmwWCwk94jgkx+OsfZATt2kKXQAJF4Lh/4HWx6Giz52TaAi0rqKj9TMJqUvhYrCmn0WD4g6H7r81Kx1DB3Y6ZreGoZBXrGN9PxSMk6WkpFfkxBlFpjb0vPLyCkqo6nNhPy9PfCyVpz+QAHcMGmSjim5e7iZNJ26Dl21gXMg7W04+glkrzWLxEXEvdltkL2mZjbp1HXcfGPM2aS4yebdbt6hLgmzLRWVVXA4r5jDuSUczi0mLbeYI9XP84opLq88/YsAnlYLMcG+RAf7EBvsW+dr8+GDj9Xgiy++aOVRdRxKmqRdqC4G35SWR1lFJT6ep9wAHNwHut8E+xfAlv+Dn3zZ9kGKyNkrOW4WcR//Ao5/Cbb8Wjst5mLdcZPNR9gQsLjN/UpNYqu0c+xECWm5NYnQ4dxiDueZSVJuUflpXyMy0JvoIF9iQ8zEp3YSVP11uL83VuvpZ+I6Yifw1qSkSdqFnlEBRAb6kF1Yxg+H8xnVPbzuQQMehgNvQnqquSZU9fp0ItJ+GYZZi3jkQzj6KeRtct7vEwldLjVnlGIvAd/I+l7FrZTaKtmfVcTerEIOZhdVJUjFHMkr4Xh+CfbTXDoL9fciIcyfhHA/EsL9q772JyHMj/gwv7r/qZQ2o6RJ2oXqfk2fbT3O2v059SdNgd2h522wdz788CeYsLLT1TSIuAW7zVzw9shHcORjKE5z3h8+omY2KXwEWN0zCSgotbE3s5C9mYXsyyxkT9XXh/OKG60p8vG0OpKgbuFmQtS1VpIU7Nuxmkx2JEqapN1I7lGVNB3I5e6GDhrwEOx/zbyrJn0pdJnYliGKSENsBcRVfIPH2rfg+GKwnajZ5+Fv3uXW9QqzkNsvpsGXaW8MwyDzZBm78y3krk3jQE6JI1HKPFnW4Hkhfl70ig6kR2SAIzGqToqiAn2w6D98bklJk7Qbyd3NuqaNh/KwVdrx8qinlsG/K/S+E3Y9D1v+ZPZk0V8+Iq5RfAyOfgxHPsIz4ytG2suhelLJNxriL4f4K83f03beN8kwDI7klbAn86QjKap+FJRWAB7wY911TmOCfegVHUivqEDzz+ggekUHEhnorcSoA1LSJO1G7+hAwvy9yCu2seVIPsMTw+o/sP9M2PsS5KyDY59B/M/aNlCRzsowzM78Rz8yL73lrHPssgCFljj8+lyLR7erICK53V52s9sNDuYUse1YAduP5rPtWD7bjhaQX1J/UbTVAuE+BoMSo+kdG+RIkHpGB+pSWiejpEnaDavVQnL3CBZvT+e7/TkNJ01+sdD3bvjxCfNOurjJHe4OG5F2w14J2d9W1Sd9BIV7nfdHnAddr8QWexnLvtnP5EGT8WhHC79WVNrZl1XEtqrkaPvRAn48XkBhWd3eRF4eFnpGmclQzcxRIAkh3ixLXcLkyUM73KK20jxKmqRdSe4RzuLt6aw9kMtd4xo5sN8DsPuf5l05hxdBt6vbKkSRjq+yzLxL9fAiszdaWXbNPquPufht1yvNy29+XcztNhuw3yXhViurqGRPRiHbjuaz/VgB247ls+N4AaU2e51jfTyt9OsSzID4YAbEhTAgPoTeMYH13pmm2/KlmpImaVccdU0Hc6motONZX10TmEsmnPM72PYIbJ0NXX/ebi8FiLiFylI4vgTS3jPrlGwFNfu8wyDuMjNR6jIJvIJcF2eV8go724/lO11i25V+Eltl3dvWArw9ODcuhHNrJUg9owIa/vtFpAFKmqRdOSc2iBA/L/JLbGw7VsCQhNBGDv4d7P67WWNx6C3ofkObxSnSIVSUmHe6pb1rzijVXrbELw4SroKuUyB6LFhde1kqv9jGprQ81h/MZcOhPH44fIKyirozSCF+Xo7Zo3PjQxgQF0xSRECTGj2KnI6SJmlXrFYLI5PCWbojg7X7cxpPmrxDzct0P/wRts6BxGtc/he7SLtXUWyu75b2Lhz7FCqKavb5d4WEq6HbVLMzt4tqBavvZNt4qCpJOpjH7syTdXofhfl7MTghtGr2KJhz40LoGuanu9ak1ShpknbnvB5VSdOBXO64qGfjB/e5G3Y+axanHngDet7aNkGKuJOKIjj6GRx+z/yzsrhmn383syaw21SIGOWSRKnSbrDjeAEbqmaRNhzMI72gtM5x3SMDGJEYxoikMEYkhdMjMkAJkrQpJU3S7lSvQ7f+QC6VdgOPxqbVvQLNFgTf3w9bH4GkG8HDp40iFWnHbIXmsiWH3zMXw60sqdkXkGQmSglTIWJkm/c6Ky6vYHPaCdYfzGPDoVy+TztR5242T6uFc+NDGJloJkjDE8OICtLvtriWkiZpd/p1CSbI15OTpRX8eKyAgV1DGj+h929g51PmUg37XoE+v22bQEXaG1uBmSilvWvWKlXWmq0J7GHOJiVcDeHD2zRRKiyrYM2+HNbsy2HDoVy2Hyug8pQF2IJ8PBmWGFY1kxTOkIRQ/Lx1c4e0L0qapN3xqKpr+mpnJmsP5Jw+afL0g3Mfgg0zYPtj0OMW9KMtnUZFkbm+26G3zLvf7LWW9gjsZSZK3aZC2JA2S5TsdoPtxwpYtSeLVbuz2Hgoj4pTkqS4EF9GJIUzMimM4Ynh9I0NanxWWaQd0L8s0i4ldzeTpu/253Lb2B6nP6HnbfDjk+Zs09750HNG6wcp4iqVZWaCdOh/ZsJUu0YpqE9NohQ6qM0SpcyTZazLsrD03S18uy+XnKJyp/2JEf5c0CuSUd3DGZEUTnxo+15WRaQ+SpqkXXLUNR3MxW43Tn+7sIcPDHwY1t4G2+dB4s2tH6RIW7JXQuYKM1FKe995QdzAHpB4HSROg5ABbZIolVVUsuFgHqt2Z7FydxY7008CHkA6YPZGGt0zkov6RHJhnygSIwJaPSaR1qakSdqlc+OCCfTxJL/Exo70As6NO80lOoDuN8H2x6FwL9Y9LwADWz1OkVZlGJD9nXnpLe0dKE2v2efXBbpNM5OlNijmNgyDfVlFrNqdxao9WXy3P6dOp+2EAIOfDe/BxefEMCwxrP5Ft0XcmJImaZc8PawMTwxj5e4s1u7PbVrSZPWCgbNhzS+x7noGT69/tH6gIi3NMODEVnNG6dBbUHSwZp93uHnXW+J1EDW21bvg5xfbWL0vm6/3ZLFqdzZHT5Q47Y8K8uHC3lFc2CeS5KRQ1q5cyuSJvbU+m3RYSpqk3TqvRwQrd2fx0Q/HuOX8pKb1Y0m8Drb/BUvBDnryMTC11eMUaREn95pJ0qH/mV3uq3kGmF25E6+D2Ing4d2qYRzILmLpjxmk/pjBhkO51K7f9vawMqp7OGN7m5fczokNcvxean026QyUNEm7ddWweP7+1R5+OHyCz7emc9mgLqc/yeoBgx6Bb6bS0/YxlOWAV2zrBytyJoqPwqG3zWQpd33Ndqs3xE02E6X4n4Gnf6uFYLcbfH/4BKk/ZrB0RwZ7Mwud9veMCuDCPlFc2CeK87pHqA2AdGpKmqTdig725faxPXh+2R6eWLyTif1j8PZsQo1Ewi8wQgbhlb+Fyl1Pw/C/tn6wIk1VngeHPoKDCyFzJVA1lWOxQswESLwWEn5uLhPUSkptlXyzJ5vUHzNYtjOD7MKaO908rRbO6xHBxP4xjO8XTdew1kvYRNyNkiZp1359YQ8WrksjLbeY/3x3iFsv6H76kyxWKgfMwXP1L7Du/Sf0/z34xbR+sCINqSzDcvRjRpY+g+cnm8Be63b8qPPNGaVuU8E3utVCyC4s46udmaT+mMHXe7KciriDfDy5+JxoJvaP4aI+UYT4qSZJpD5KmqRdC/DxJGViH2Yt2srfv9rD1cO7NukvdKPLZeRZexNWuQd+fByGP9sG0YrUYtgh6xs48CakvYun7QRx1ftCBkD3G81ZpYDEVgthX1ahoz5pY1qe04K38aF+TOgXzcT+sYzqHt60WVyRTk5Jk7R7U4d35dVvDrAns5B/Lt/LrMn9Tn+SxcIO7xsYUzoH9vwL+t1vruAu0tryfzQTpYP/NZutVjH84tlbMZKki/+EV9TwVnnrSrvB92l5pP6YQeqODPZnFTntHxAfzIR+MUzsH0P/LsFa7FakmZQ0Sbvn6WHlj5P7ccuC9by2+iA3npdIQvjp6yyyrIOxR16ANfsb2P4XGPnPNohWOqXiY+Zdbwf/C3nf12z3CjbXeut+IxVho/nxiyUkhQ5q0beuqLSzel8On205xrIdmU6duL08zPqkS/rHML5fDHHqwi1yVpQ0iVu4uG8UY3pG8O2+HJ76chfPXzv09CdZLNgHzMW6Yjzsexn6PQCBTaiJEmkKWwEc/gAOvgnpy3AUdFu9oMtPzctvcT8z10YEaMFb8u12g01peXz8wzE+33rcqZA72NeTcVX1SRf2iSLYV/VJIi1FSZO4BYvFwh8n9+Nnf/+GjzYf49YLujOoa+hpzzOixpq9bdJTYdujcN6rrR+sdFx2m7nm28H/wpGPoLJWs8eo8yHpRrOg2yeixd/aMAx+PF7Axz8c49Mfjjs1mgwP8GbywFgmD+jCyO7h6sQt0kqUNInbGBAfwi+GxrPo+6P85fMd/O/285pWkzHoUTNpOvAG9J8JwX1aP1jpOAwDctZWFXS/DWXZNfuC+5qJUtL15vpvreBAdhEfbz7Gxz8cZV+tGqVAH08uOTeGKwbHcX6vSCVKIm1ASZO4lfsn9eXTrcf5bn8uy3ZkMqF/E1oJRCabl0mOfQpb58L5/239QMX9FewxZ5QOvgmF+2q2+8aYLQKSboDw4a2y5lt6fimfbjnGR5uPsfVovmO7t6eVn/SN5sohcYw7JxpfLzWaFGlLSprErcSH+vGr87szf+U+5n2xg4v7RuHZlP9hD3rETJoO/Q/OnQWhA1o/WHE/pVlmh+6Db5qzS9U8/M2Gk0m/hNjxYG35vzrzisr5fNtxPt58jHUHcx3tATysFs7vFckVg+O45NwY1SiJuJCSJnE7vx3Xk7fXp7Evq4i3NxzmhuQm9LkJH2rexXT4Pdj8IFz4casvdipuoqIYjn4CB/5j1isZFeZ2ixViLzEvv3W9ErwCW/ytC8sqSP0xnY83H+PrPdlU1FrobWRSGFcMjuOnA7sQGejT4u8tIs2npEncTrCvF/eO782cT37k2dTdXDkknkCfJvwoD5oLRz6AY5/Dqivh/P+BV1DrByztj70SMleYM0pp70PFyZp94SPMRClxGvi1/LqFFZV2Vu3NYNH3R1m2I8OpM/e5ccFcMTiOnw2OI17tAUTaHSVN4pauT05kwbcHOZhTzL9X7iPlkr6nPymkP5z/Nqy5EY59BqkXwEWfQEC31g9YXM8w4MQWM1E6uBBKjtXsC0iqKui+AULOaZW335NZyEcHrTz61CqnFgHdIwO4fHAcVwyOo1d0y89miUjLUdIkbsnb08qDl57Db/67iX9/vZ/rkxOJDfE9/YndrjKTpJVXmP+ALhllJk4RI1s/aHGNosNwaKF591v+tprt3mHQ7RozWYoaY16Oa2H5JTY++eEY7248wg+HTwBWoJyIAG+mDI1nypB4BsSrM7eIu1DSJG7r0gGxDE8MY+OhPJ5J3cWTVw9u2okRI2HSWlh5uZk4Lb0IRr8B3a5u3YCl7ZTnw+H3zVmljBXUNJ70hvjLzUQp7qfg0fK1QpV2g2/3ZfPuhiMs2Z5OWYV5+c3TaqFfSCW/uXQYEwd0UYsAETekpEncVnXDy6v+9S3vbjzCry7ozjmxwU07OaAbTPwGVl9nXqr7ZioM/ovZx0n/63dPFcVw9FM49JZZt2Yvq9kXfVFV48mrwTu0Vd7+YHYR7286wvsbj3Asv9SxvW9MEFNHdOWyAdGsW7WMif2jlTCJuCm3SZpyc3O5++67+eSTT7BarVx11VU8//zzBAY2XAPw73//m4ULF7Jp0yZOnjxJXl4eoaGhbRe0tLrhiWFMHhjL51vTmff5Tl7/1aimn+wVBBd+BN/fD7uehx/+CAW7YNS/wcO79YKWllNZZt7xdugtOPoxVNRaoDakv9kiIOk6CGjCHZZnoKisgs+2Hue9DUdYdzDXsT3Y15Mrh8QzdURXBsaHYLFYsLXgMioi4hpukzTdcMMNHD9+nNTUVGw2G7fccgu//vWvWbhwYYPnFBcXc+mll3LppZcya9asNoxW2tIfJp1D6o8ZrNydxdd7shjbO6rpJ1s9YPhzENQHNt4DB16HogMwdlGrLIUhLcBeARlfmYnS4UVgq2n+SEB3SLzWfIQObJVZQ8MwWHcgl3c3HuHzrccpLq8EzLca2zuKqcO7MrF/jBpPinRAbpE07dixg8WLF7N+/XpGjBgBwN///ncmT57MU089RVxcXL3n3XfffQCsWLGiye9VVlZGWVnNtH5BQQEANputw/1PsXo87j6u+BBvrh+VwOtr0vjzZzv48Dch2CvNXjtNHlv327H4JeKx5nosmaswlpxHxQUfmslUO9NRPrf6NDg2w44lezWWw+9gPbIIS1lWzS7fOOwJUzG6XYMRNqImUaqoaNHYjueXsuj7Yyz6/ihpuTXrviWG+3PVsDimDImji+NmBDu2Wq0EGh1bB9GRx6exuafWGJPFMAzj9Ie51quvvsr9999PXl6eY1tFRQW+vr68++67/PznP2/0/BUrVjBu3LgmXZ6bM2cOc+fOrbN94cKF+Pv7n1H80vqKbPDo9x6UVFq4oWclo6LP7Mc6yJ5GculjBBiZlBPIOt8HyfEY2MLRSpMYBqH2PcRXfEN85Wr8jBzHrjKCOeY5hqOeY8mx9muVO98AKu2wNc/CmgwLu/ItGJgJmY/VYEiEQXK0nR5BKoMTaY+Ki4u5/vrryc/PJzi4ifWup+EWM03p6elER0c7bfP09CQ8PJz09PQWfa9Zs2aRkpLieF5QUEBCQgLjxo0jIqJjXa6x2WykpqYyceJEvLzcf2mGExEHeHLJHpZl+ZNyTTLfrPjqzMZW+gvsq6/CO3ct55fNpXL4PzG639wqMZ+Jjva51WYrL2ftly9zQcJRPI++j6V0v2Of4RWCET8Fe8I1WKPH0dXqSddWiiMtt5h3Nx7lvU1HnXoqJXcP46qh8Uw6Nxp/7+b99dmRPzfo2OPT2NxTTk7O6Q9qJpcmTTNnzuSJJ55o9JgdO3a0UTQmHx8ffHzq3obs5eXV4X6gqnWUsf3qgp78d+0Rjp4o4b/rj5HIGY7NKx4mLIe1v8Jy6C08N/waivbCkHmtNqNxJjrK5wZAwW449DaeBxcyrmQn7K7a7uFvLmGSeC2WLpOwePjQWp9AeYWdpTsy+N+6NL7ek+3YHhnowzUjujJtZAKJEQFn/T4d6nOrR0cen8bmXlpjPC5Nmu6//35uvvnmRo/p0aMHsbGxZGZmOm2vqKggNzeX2NiWX+ZA3JOvlwcPTOrLfW9v5sWvDzDrbK6qefrBmIVmTdO2R2DHk1C4F0b/Bzx1mfas2Ssh5ztzzbejn0D+jwBYgEq8sMRPxpp0PcRfBp5nn6g05lBOEf9bd5j3Nh52zCpVF3VfPyqB8f1i1CJARAAXJ01RUVFERZ3+TqfRo0dz4sQJNm7cyPDhwwH46quvsNvtJCcnt3aY4kauGBzHy9/sZ9vRApYctjLtbF7MYjHXqwvqDWtvNe/UKjpkLvbrX//NB9IIW4HZHuDop2YfpbKa2RwsnhA7kYquV7Nkuy+XjJmKtRX/11teYSf1R3NW6Zu9NXFEBfkwbUQC00YmkBCu5FhEnLlFTVO/fv249NJLuf3225k/fz42m40ZM2Zw7bXXOu6cO3r0KOPHj+eNN95g1CizV096ejrp6ens3bsXgK1btxIUFES3bt0IDw932Xik9VitZsPL619ay+oMC/uziugbF3p2L9r9RnNtsq9/Drkb4ctkc+mVsCEtEHEHV3igZjYpcyXYa93N4h0GXX5qduiOmwTeYRg2GxU/ft5q4RzMLuJ/69N4b8MRcopqZpUu7B3FdaO6Mb6fGk+KSMPcImkC+O9//8uMGTMYP368o7nl3/72N8d+m83Grl27KC4udmybP3++051wF154IQCvvfbaaS8Livsa0zOScX0jWb4rm6dS9/DS9BZYVy76AnPplRWXQcFOc7HfMf+Drpef/Wt3JE6X3T6F/O3O+4P6mElS/OUQdT5YW/+voPIKO1/+mM7/1qWxem9NYWh0kA/TRiZwzQjNKolI07hN0hQeHt5oI8ukpCRO7Z4wZ84c5syZ08qRSXv0wCV9WLEri9Qdmaw7kMuo7i0wsxjYAy5ZA19fDRnLYNWVMOxp6Htf577n3FYAx780E6U6l908IGosxP/MTJSC267v1YHsIt5al8Z7G51nlS7uY84q/eScaDw1qyQizeA2SZNIc/SODmR0jMG3GRb+/PkOPvztmJZZSd47FMZ9ARtmwN5/w6YUOLEN+syAsMHt6u66VtXYZTevUHMx3PjLIe5S8zJcGymvsLNkezoL16axZn/NrFJMsFmrdM3IBLqGaVZJRM6MkibpsH7a1c7mPC9+OHyCT7cc5/LBLVS8bfWCkfMhqC98/3vY/6r58ImC2InQ5RLz4delZd7P1SqKIPd7yFkHuevNPwv3Ox8T1PuUy25te+vywewi/lfPrNK4vtFcN6ob4/pGaVZJRM6akibpsIK94bYLkvjbV/t4cslOLjk3Bh/PFloPzGKBfikQOgB2/8NcC60sCw4tNB9grn0WW5VARY012xi0d3abWYeUsw5yqhKk/G1gOC8JYl52u6AqUfoZBPdt81Cr74BbuO6QU61STLAP00Z2Y9rIBOJD3eB7LiJuQ0mTdGi3np/IW+uPcDi3hP+sOcRtY3u07BtUzypVlkP2Gkj/0qzvyd0IJ7aaj51Pg9UHoi80j429pNUWk20Ww4DCfTXJUc46yPseKkvqHuvXBSJGQfhI88+IkealShdoqK/SRX2iuF61SiLSipQ0SYfm7+3J/Zf04cH3t/L3r/YydXgCIf6tcOnIwxtiLjIfg/8MpdlmsfjxL81EqvgIpKeaDx4A39iaBCp2AvjFtHxMpypJr0mQctebX5fn1j3OK7gqOapOkEaBf3zrx9cIW2VNX6Xa3bqr74CbplolEWkDSpqkw7t6eAKvfnOQXRkn+cfyPTx0Wf/Wf1PfSEicZj4Mw2xTUJ1AZayA0nQ48Ib5ALPnk+NS3vng4Qv2Cqgshopic/anohgqi7GUFRBdsRHLkVKg3GkfFcXOX1cWmzVJ+duh+HDdOK3eEDbUOUEK6t1uCtoP5xbzv3VpvLPhCNmFZUDtbt3qqyQibUtJk3R4HlYLsyafw82vref1bw9x0+iktu3LY7FASD/zcc69UFkGWatrLuXlfQ95m83Hjidriqhr35FWiycwGmBNswMxY6hOjsJHQuggc5asHam0w5LtGbyz6Rhf78miupNI9Rpw143qpr5KIuISSpqkU7ioTxQX9Irkm73ZzP3kR/55wzC8PV00Q+HhA7E/MR9DHofSTEhfWjMTVXK8nnP8zTXvPPwxPPzIL7IRHN4Fq2eAWWBea3+dPz38ILA7hA8Hr6C2H28THckr5r/fHeS/mzwoWPuDY/vY3pFcP6obE/prDTgRcS0lTdIpWCzmbNPlf/+GpTsyuHr+tzx/7VC6R7buYrBN4hsNSdebD8OA4jTz7jSPqmTIw9epaLzCZmPl558zedzkVl2frS2UVVTy1Y5M3t5wmJW7q2eVLEQEeDN1RALXjUogMaIdfEYiIihpkk7k3LgQ5t84nAfe28KWI/lc9reveeTKAVw1LL5lGl+2BIsFAhJdHUWrMgyD7ccKeHfDYT764RgnimsuQ47pEU4fjyweuP5CAvx8XBiliEhdSpqkU7nk3FgGdg3hvrc2s/ZALr9/9wdW7s7izz8fQLCve8/atHdZJ8v4aPNR3tt4hJ3pJx3bY4J9+PnQruYdcCHefP755667dCoi0gglTdLpdAnxY+Ht5zF/5T6eSd3NJz8c4/u0PJ6/dgjDE1tgjTpxKK+w89XODN7beITlu7KotJtV3d6eVi7pH8PVw7sytncUHlZzps9mq7/4XUSkPVDSJJ2Sh9XCXeN6MaZnBPe89T2Hc0u45sXvuOcnvZnxk16Of8Sl+aovv7238QgfbT5KXq3Lb0MSQrl6eFcuHxTXOv2yRERakZIm6dSGdgvj83vG8n8fbuPDzcd4duluVu/N5tlrh2gJjmbKLizjw+/rXn6LDvLhF8O6cvXweHpFt9+790RETkdJk3R6Qb5ePHftUC7qG8X/fbiddQdz+elzq3j8qkFMHthBFt1tJeUVdpbvyuTdDUdYsSuTinouv13QK1LLmohIh6CkSaTKz4d2ZVi3MO55azM/HD7Bb/+7iWkjEph9RX/8vfWrUtv2Y/lVl9+OkVtU7tg+uOry2xW6/CYiHZD+JRCpJTEigPfuHM1zS3fzzxX7eHvDYdYfzOVv1w1lQHyIq8NzmUq7waa0PJbuyGDZjkz2ZhY69kUH+fDzYfFcPawrvWN0+U1EOi4lTSKn8PKw8sCkc7igVxS/e3sz+7OL+Pk/V/Pgpefwq/O7Y+0kReInS22s2p3Nsh0ZLN+V6VTQ7e1hZeK5VXe/6fKbiHQSSppEGjC6ZwRf3DuWB9/fwpc/ZvDYZztYuTuLp68ZTHSQr6vDaxWHc4sds0lrD+RgqzQc+0L8vLi4bxTj+8VwUZ8oQvx0+U1EOhclTSKNCAvw5sVfDmfhujQe/fRHvt6TzU+f+5qnpg5m3DnRrg7vrFXaDTYfzmPpjkyW7chgd0ah0/4ekQGM7xfN+H4xjEgM04ySiHRqSppETsNisXBDciKjksK5+3/fszP9JLcsWM/NY5KY+dNz8PXycHWIzVJUVsHXe7JYuiOT5TszyalVyO1htTAiMYwJ/WIY3y+aHlGBLoxURKR9UdIk0kS9Y4L48K7zeWLxTl5bfZAF3x7ku/05/O26ofRp5wXQR0+UsGxHBkt3ZPLdvhzKK+2OfUG+nlzUJ4qJ/c3LbqH+3i6MVESk/VLSJNIMvl4ezL78XC7sHcXv3/2BneknueTZVcQE+9AzKpAeUQH0jAo0H9GBdAn2bbPCcbvdIONkKQeyiziYXczBnCIOZBexL6uQ/VlFTscmRvgz/pwYJvSLZmT3cLx02U1E5LSUNImcgXHnRPPFfWOZ+f5WvtqZSUZBGRkFZXy7L8fpOF8vKz0izQSqR2QAPaMD6RkVQI/IQPy8m39ZzzAMsk6Wsa8A3t14hLS8Mg5mF3Ewx3yU2uz1nme1wPDEMMb3MxOlnlGBWCyd4y5AEZGWoqRJ5AxFB/ny6s0jyS+2sS/bnM3Zl1XIvsxC9mcXcTDbTGJ+PF7Aj8cL6pwfH+pXMzMVHUjPqqQqOsiH3KLyqpmiYg5mF3Egx3y9g9lFFJVXAp6w/cc6r+lhtdAt3J+kCH+SIgPoHhlAUkQAA+JDCA/QZTcRkbOhpEnkLIX4ezGsWxjDuoU5bbdV2jmcW1yTTFVdJtubVciJYhtHT5Rw9EQJX+/JdjrPy8PidKv/qawWCPM26JcQSY+oQJIiqpKjyAC6hvnpUpuISCtR0iTSSrw8rPSICqRHVCATiHHal1tUzv6qRGpfVlHV10Wk5RY7Eqa4EF/HbFH1jFFSZACxQV4s+3IxkycPx8tLvZJERNqKkiYRFwgP8CY8IJwRSeFO28sr7GQUlBIV5NNgKwObzVbvdhERaV1KmkTaEW9PKwnh/q4OQ0RE6qHiBxEREZEmUNIkIiIi0gRKmkRERESaQEmTiIiISBMoaRIRERFpAiVNIiIiIk2gpElERESkCZQ0iYiIiDSBkiYRERGRJnCbpCk3N5cbbriB4OBgQkNDufXWWyksLGz0+Lvvvpu+ffvi5+dHt27duOeee8jPz2/DqEVERKSjcJuk6YYbbmD79u2kpqby6aefsmrVKn796183ePyxY8c4duwYTz31FNu2bWPBggUsXryYW2+9tQ2jFhERkY7CLdae27FjB4sXL2b9+vWMGDECgL///e9MnjyZp556iri4uDrnDBgwgPfff9/xvGfPnvz5z3/mxhtvpKKiAk9Ptxi6iIiItBNukTmsWbOG0NBQR8IEMGHCBKxWK2vXruXnP/95k14nPz+f4ODgRhOmsrIyysrKnM4B83JfR2Oz2SguLiYnJwcvLy9Xh9OiNDb3pLG5r448Po3NPVX/u20YRou9plskTenp6URHRztt8/T0JDw8nPT09Ca9RnZ2No8++mijl/QA5s2bx9y5c+ts79OnT9MDFhERkXYhJyeHkJCQFnktlyZNM2fO5Iknnmj0mB07dpz1+xQUFHDZZZfRv39/5syZ0+ixs2bNIiUlxfH8xIkTJCYmkpaW1mLf9PaioKCAhIQEDh8+THBwsKvDaVEam3vS2NxXRx6fxuae8vPz6datG+Hh4S32mi5Nmu6//35uvvnmRo/p0aMHsbGxZGZmOm2vqKggNzeX2NjYRs8/efIkl156KUFBQXzwwQennX708fHBx8enzvaQkJAO9wNVLTg4WGNzQxqbe+rIY4OOPT6NzT1ZrS13z5tLk6aoqCiioqJOe9zo0aM5ceIEGzduZPjw4QB89dVX2O12kpOTGzyvoKCASZMm4ePjw8cff4yvr2+LxS4iIiKdi1u0HOjXrx+XXnopt99+O+vWrWP16tXMmDGDa6+91nHn3NGjRznnnHNYt24dYCZMl1xyCUVFRbzyyisUFBSQnp5Oeno6lZWVrhyOiIiIuCG3KAQH+O9//8uMGTMYP348VquVq666ir/97W+O/TabjV27dlFcXAzApk2bWLt2LQC9evVyeq0DBw6QlJTUpPf18fFh9uzZ9V6yc3cam3vS2NxTRx4bdOzxaWzuqTXGZjFa8l48ERERkQ7KLS7PiYiIiLiakiYRERGRJlDSJCIiItIESppEREREmkBJE/DCCy+QlJSEr68vycnJjrYFDXn33Xc555xz8PX1ZeDAgXz++edtFGnzNWdsCxYswGKxOD3aa2+rVatWcfnllxMXF4fFYuHDDz887TkrVqxg2LBh+Pj40KtXLxYsWNDqcZ6J5o5txYoVdT43i8XS5CWG2sq8efMYOXIkQUFBREdHM2XKFHbt2nXa89zl9+1Mxucuv3P/+te/GDRokKMB4ujRo/niiy8aPcddPrfmjs1dPrP6PP7441gsFu67775Gj3OXz662poytJT67Tp80vf3226SkpDB79mw2bdrE4MGDmTRpUp0O5NW+/fZbrrvuOm699Va+//57pkyZwpQpU9i2bVsbR356zR0bmF1hjx8/7ngcOnSoDSNuuqKiIgYPHswLL7zQpOMPHDjAZZddxrhx49i8eTP33Xcft912G0uWLGnlSJuvuWOrtmvXLqfP7tT1Gl1t5cqV3HXXXXz33XekpqZis9kcvdQa4k6/b2cyPnCP37muXbvy+OOPs3HjRjZs2MBPfvITrrzySrZv317v8e70uTV3bOAen9mp1q9fz4svvsigQYMaPc6dPrtqTR0btMBnZ3Ryo0aNMu666y7H88rKSiMuLs6YN29evcdfc801xmWXXea0LTk52bjjjjtaNc4z0dyxvfbaa0ZISEgbRddyAOODDz5o9Jg//OEPxrnnnuu0bdq0acakSZNaMbKz15SxLV++3ACMvLy8NomppWRmZhqAsXLlygaPcafft1M1ZXzu+jtnGIYRFhZmvPzyy/Xuc+fPzTAaH5s7fmYnT540evfubaSmphoXXXSRce+99zZ4rLt9ds0ZW0t8dp16pqm8vJyNGzcyYcIExzar1cqECRNYs2ZNveesWbPG6XiASZMmNXi8q5zJ2AAKCwtJTEwkISHhtP/bcifu8rmdjSFDhtClSxcmTpzI6tWrXR3OaeXn5wM0upimO39uTRkfuN/vXGVlJW+99RZFRUWMHj263mPc9XNrytjA/T6zu+66i8suu6zOZ1Ifd/vsmjM2OPvPrlMnTdnZ2VRWVhITE+O0PSYmpsF6kPT09GYd7ypnMra+ffvy6quv8tFHH/Hmm29it9sZM2YMR44caYuQW1VDn1tBQQElJSUuiqpldOnShfnz5/P+++/z/vvvk5CQwMUXX8ymTZtcHVqD7HY79913H+effz4DBgxo8Dh3+X07VVPH506/c1u3biUwMBAfHx/uvPNOPvjgA/r371/vse72uTVnbO70mQG89dZbbNq0iXnz5jXpeHf67Jo7tpb47NxmGRVpfaNHj3b639WYMWPo168fL774Io8++qgLI5PG9O3bl759+zqejxkzhn379vHss8/yn//8x4WRNeyuu+5i27ZtfPPNN64OpVU0dXzu9DvXt29fNm/eTH5+Pu+99x7Tp09n5cqVDSYX7qQ5Y3Onz+zw4cPce++9pKamuk2xelOdydha4rPr1ElTZGQkHh4eZGRkOG3PyMggNja23nNiY2ObdbyrnMnYTuXl5cXQoUPZu3dva4TYphr63IKDg/Hz83NRVK1n1KhR7TYhmTFjBp9++imrVq2ia9eujR7rLr9vtTVnfKdqz79z3t7ejnU8hw8fzvr163n++ed58cUX6xzrbp9bc8Z2qvb8mW3cuJHMzEyGDRvm2FZZWcmqVav4xz/+QVlZGR4eHk7nuMtndyZjO9WZfHad+vKct7c3w4cPZ9myZY5tdrudZcuWNXg9e/To0U7HA6SmpjZ6/dsVzmRsp6qsrGTr1q106dKltcJsM+7yubWUzZs3t7vPzTAMZsyYwQcffMBXX31F9+7dT3uOO31uZzK+U7nT75zdbqesrKzefe70udWnsbGdqj1/ZuPHj2fr1q1s3rzZ8RgxYgQ33HADmzdvrjepcJfP7kzGdqoz+uzOqoy8A3jrrbcMHx8fY8GCBcaPP/5o/PrXvzZCQ0ON9PR0wzAM45e//KUxc+ZMx/GrV682PD09jaeeesrYsWOHMXv2bMPLy8vYunWrq4bQoOaObe7cucaSJUuMffv2GRs3bjSuvfZaw9fX19i+fburhtCgkydPGt9//73x/fffG4DxzDPPGN9//71x6NAhwzAMY+bMmcYvf/lLx/H79+83/P39jQceeMDYsWOH8cILLxgeHh7G4sWLXTWEBjV3bM8++6zx4YcfGnv27DG2bt1q3HvvvYbVajWWLl3qqiHU6ze/+Y0REhJirFixwjh+/LjjUVxc7DjGnX/fzmR87vI7N3PmTGPlypXGgQMHjC1bthgzZ840LBaL8eWXXxqG4d6fW3PH5i6fWUNOvcPMnT+7U51ubC3x2XX6pMkwDOPvf/+70a1bN8Pb29sYNWqU8d133zn2XXTRRcb06dOdjn/nnXeMPn36GN7e3sa5555rfPbZZ20ccdM1Z2z33Xef49iYmBhj8uTJxqZNm1wQ9elV32Z/6qN6PNOnTzcuuuiiOucMGTLE8Pb2Nnr06GG89tprbR53UzR3bE888YTRs2dPw9fX1wgPDzcuvvhi46uvvnJN8I2ob0yA0+fgzr9vZzI+d/md+9WvfmUkJiYa3t7eRlRUlDF+/HhHUmEY7v25NXds7vKZNeTUxMKdP7tTnW5sLfHZWQzDMJo+LyUiIiLSOXXqmiYRERGRplLSJCIiItIESppEREREmkBJk4iIiEgTKGkSERERaQIlTSIiIiJNoKRJREREpAmUNImIiIg0gZImEWmyiy++mPvuu8/xPCkpieeee85l8bSWOXPmMGTIEFeHISLtjJImkXbu5ptvZsqUKXW2r1ixAovFwokTJxo8d8GCBYSGhta7z2Kx8OGHH55VbOvXr+fXv/51k451pwTr97//fZ1FS89USUkJ4eHhREZGNnkR2JbUlJ8TEWkaJU0icsaioqLw9/d3dRgtLjAwkIiIiBZ5rffff59zzz2Xc84556yT1NZUXl7u6hBE2j0lTSJSr6KiIm666SYCAwPp0qULTz/9dJ1jas8eGYbBnDlz6NatGz4+PsTFxXHPPfcA5mW9Q4cO8bvf/Q6LxYLFYgEgJyeH6667jvj4ePz9/Rk4cCD/+9//nN7j4osv5p577uEPf/gD4eHhxMbGMmfOHKdjTpw4wR133EFMTAy+vr4MGDCATz/91LH/m2++YezYsfj5+ZGQkMA999xDUVFRg2M/9fJc9WzfU089RZcuXYiIiOCuu+7CZrOd9vv4yiuvcOONN3LjjTfyyiuv1NlvsVh4+eWX+fnPf46/vz+9e/fm448/djrm448/pnfv3vj6+jJu3Dhef/11p9mjQ4cOcfnllxMWFkZAQADnnnsun3/+OQcPHmTcuHEAhIWFYbFYuPnmmx3f1xkzZnDfffcRGRnJpEmTAFi5ciWjRo3Cx8eHLl26MHPmTCoqKpw+j7vvvpv77ruPsLAwYmJieOmllygqKuKWW24hKCiIXr168cUXX5z2eyPibpQ0iUi9HnjgAVauXMlHH33El19+yYoVK9i0aVODx7///vs8++yzvPjii+zZs4cPP/yQgQMHArBo0SK6du3KI488wvHjxzl+/DgApaWlDB8+nM8++4xt27bx61//ml/+8pesW7fO6bVff/11AgICWLt2LU8++SSPPPIIqampANjtdn7605+yevVq3nzzTX788Ucef/xxPDw8ANi3bx+XXnopV111FVu2bOHtt9/mm2++YcaMGc36fixfvpx9+/axfPlyXn/9dRYsWMCCBQsaPWffvn2sWbOGa665hmuuuYavv/6aQ4cO1Tlu7ty5XHPNNWzZsoXJkydzww03kJubC8CBAwe4+uqrmTJlCj/88AN33HEHDz30kNP5d911F2VlZaxatYqtW7fyxBNPEBgYSEJCAu+//z4Au3bt4vjx4zz//PNO31dvb29Wr17N/PnzOXr0KJMnT2bkyJH88MMP/Otf/+KVV17hscceq/N5REZGsm7dOu6++25+85vfMHXqVMaMGcOmTZu45JJL+OUvf0lxcXGzvsci7Z4hIu3a9OnTDQ8PDyMgIMDp4evrawBGXl5eg+e+9tprBlDn3ICAAAMwPvjgg3rPO3nypOHt7W288847jm05OTmGn5+fce+99zq2JSYmGs8++6xhGIbx9NNPG3369DHKy8vrfc3axzbmsssuM+6//37H84suusi44IILnI4ZOXKk8eCDDxqGYRhLliwxrFarsWvXrnpf79ZbbzV+/etfO237+uuvDavVapSUlNR7zuzZs43Bgwc7nk+fPt1ITEw0KioqHNumTp1qTJs2rdGx/PGPfzSmTJnieH7llVcas2fPdjoGMP70pz85nhcWFhqA8cUXXxiGYRgPPvigMWDAAKdzHnroIafPfuDAgcacOXPqjWH58uX1/pxcdNFFxtChQ+vE27dvX8Nutzu2vfDCC0ZgYKBRWVnpOK/251FRUWEEBAQYv/zlLx3bjh8/bgDGmjVr6o1JxF1ppknEDYwbN47Nmzc7PV5++WWnYwIDAx2PO++807E9KCiozrmbN29u9P327dtHeXk5ycnJjm3h4eH07du3wXOmTp1KSUkJPXr04Pbbb+eDDz5wuqxTn8rKSh599FEGDhxIeHg4gYGBLFmyhLS0NKfjBg0a5PS8S5cuZGZmArB582a6du1Knz596n2PH374gQULFjh9fyZNmoTdbufAgQONxlfbueee65i9OjWGhsb2+uuvc+ONNzq23XjjjSxYsAC73d7g+AICAggODna89q5duxg5cqTT8aNGjXJ6fs899/DYY49x/vnnM3v2bLZs2dKkMQ0fPtzp+Y4dOxg9erTj8inA+eefT2FhIUeOHKk3Xg8PDyIiIhyzigAxMTEAjX5/RNyRp6sDEJHTCwgIoFevXk7bav8jBjglQsHBwY6vrVZrnXNbQ0JCArt27WLp0qWkpqby29/+lr/+9a+sXLkSLy+ves/561//yvPPP89zzz3HwIEDCQgI4L777qtTlHzq+RaLxZF4+Pn5NRpXYWEhd9xxh6O+qrZu3bo1eXyNxVCfJUuWcPToUaZNm+a0vbKykmXLljFx4sQzfu1T3XbbbUyaNInPPvuML7/8knnz5vH0009z9913N3peQEBAk9+jtvrirb2tOulqzhhE3IFmmkQ6iF69ejke0dHRZ/VaPXv2xMvLi7Vr1zq25eXlsXv37kbP8/Pz4/LLL+dvf/sbK1asYM2aNWzduhUAb29vKisrnY5fvXo1V155JTfeeCODBw+mR48ep32PUw0aNIgjR440eN6wYcP48ccfnb4/1Q9vb+9mvVdzvPLKK1x77bV1ZviuvfbaegvCG9K3b182bNjgtG39+vV1jktISODOO+9k0aJF3H///bz00ksAjjGe+r2vT79+/VizZg2GYTi2rV69mqCgILp27drkmEU6KiVNIlJHYGAgt956Kw888ABfffUV27Zt4+abb8ZqbfivjAULFvDKK6+wbds29u/fz5tvvomfnx+JiYmAeafdqlWrOHr0KNnZ2QD07t2b1NRUvv32W3bs2MEdd9xBRkZGs2K96KKLuPDCC7nqqqtITU3lwIEDfPHFFyxevBiABx98kG+//ZYZM2awefNm9uzZw0cffdTsQvDmyMrK4pNPPmH69OkMGDDA6XHTTTfx4YcfOgq9T+eOO+5g586dPPjgg+zevZt33nnHUYBePaNz3333sWTJEg4cOMCmTZtYvnw5/fr1AyAxMRGLxcKnn35KVlYWhYWFDb7Xb3/7Ww4fPszdd9/Nzp07+eijj5g9ezYpKSmNfvYinYV+C0SkXn/9618ZO3Ysl19+ORMmTOCCCy6oUwNTW2hoKC+99BLnn38+gwYNYunSpXzyySeOfkePPPIIBw8epGfPnkRFRQHwpz/9iWHDhjFp0iQuvvhiYmNj623keTrvv/8+I0eO5LrrrqN///784Q9/cMysDBo0iJUrV7J7927Gjh3L0KFDefjhh4mLi2v+N6WJ3njjDQICAhg/fnydfePHj8fPz48333yzSa/VvXt33nvvPRYtWsSgQYP417/+5bh7zsfHBzBnke666y769evHpZdeSp8+ffjnP/8JQHx8PHPnzmXmzJnExMQ0mizGx8fz+eefs27dOgYPHsydd97Jrbfeyp/+9KfmfgtEOiSLUXseVkRE2r0///nPzJ8/n8OHD7s6FJFORYXgIiLt3D//+U9GjhxJREQEq1ev5q9//WurXl4UkfopaRIRaef27NnDY489Rm5uLt26deP+++9n1qxZrg5LpNPR5TkRERGRJlAhuIiIiEgTKGkSERERaQIlTSIiIiJNoKRJREREpAmUNImIiIg0gZImERERkSZQ0iQiIiLSBEqaRERERJrg/wHP1hLItT1aXAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt \n",
    "#plot\n",
    "true_val = (h2_dataset.y) \n",
    "predict_val = (predict)*(-1)\n",
    "pos = np.array([0.5000, 0.6842, 0.8684, 1.0526, 1.2368,\n",
    "1.4211,\n",
    "1.6053,\n",
    "1.7895,\n",
    "1.9737,\n",
    "2.1579,\n",
    "2.3421,\n",
    "2.5263,\n",
    "2.7105,\n",
    "2.8974,\n",
    "3.0789,\n",
    "3.2632,\n",
    "3.4474,\n",
    "3.6316,\n",
    "3.8158,\n",
    "4.000]) \n",
    "plt.plot(pos, true_val )\n",
    "plt.plot(pos, predict_val, color = 'orange')\n",
    "y = pos * 0\n",
    "plt.xlabel(\"H-H distance in Angstrom\") \n",
    "plt.ylabel(\"Energy in Hartree\")\n",
    "plt.xlim([0.0, 4.5])\n",
    "plt.ylim([-0.2, 0.55])\n",
    "plt.grid()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a45d550",
   "metadata": {},
   "source": [
    "#### Notes \n",
    "\n",
    "- The entry type \"Density Matrix\" cannot be used on model.evaluate as of now.\n",
    "- To run predictions on this data type, a dataset containing only \"dm\" entries must be used.\n",
    "- When initializing the XCModel, the user may build and pass a different pytorch model to train the XC Functional, instead of using the default method. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c1076ca1",
   "metadata": {},
   "source": [
    "## References \n",
    "\n",
    "- Kasim, Muhammad F., and Sam M. Vinko. \"Learning the exchange-correlation\n",
    "    functional from nature with fully differentiable density functional\n",
    "    theory.\" Physical Review Letters 127.12 (2021): 126403.\\\n",
    "  Most of our code has been derived from the reference above. The implementation of the paper can be found in the github link below :\n",
    " https://github.com/mfkasim1/xcnn \n",
    "\n",
    "- Encyclopedia of Condensed Matter Physics, 2005.\n",
    "- Kohn, W. and Sham, L.J., 1965. Self-consistent equations including\n",
    "    exchange and correlation effects. Physical review, 140(4A), p.A1133.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21330dba",
   "metadata": {},
   "source": [
    "# Congratulations! Time to join the Community!\n",
    "\n",
    "Congratulations on completing this tutorial notebook! If you enjoyed working through the tutorial, and want to continue working with DeepChem, we encourage you to finish the rest of the tutorials in this series. You can also help the DeepChem community in the following ways:\n",
    "\n",
    "\n",
    "## Star DeepChem on [GitHub](https://github.com/deepchem/deepchem)\n",
    "This helps build awareness of the DeepChem project and the tools for open source drug discovery that we're trying to build.\n",
    "\n",
    "\n",
    "## Join the DeepChem Gitter\n",
    "The DeepChem [Gitter](https://gitter.im/deepchem/Lobby) hosts a number of scientists, developers, and enthusiasts interested in deep learning for the life sciences. Join the conversation!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
